To generate successive elements from a series, we can use java iterator. It is an improvement over Enumeration interface. Iterator takes the place of Enumeration since jdk 1.2
It is a nice utility for collections. Every collection is unique on its own and imagine if we have have to write logic on our own for every collection when there is a need to iterate it. Instead, java forces a collection to deliver an iterator.
These nice utilities makes java lovable, isn’t it?
Important points to note:
package com.javapapers; import java.util.ArrayList; import java.util.Iterator; public class ExampleIterator { public static void main(String args[]){ ArrayList animal = new ArrayList(); animal.add("Horse"); animal.add("Lion"); animal.add("Tiger"); Iterator animalItr = animal.iterator(); while(animalItr.hasNext()) { String animalObj = (String)animalItr.next(); System.out.println(animalObj); } } }
Without generics, Iterator returns the Object and we need to typecast it.
package com.javapapers; import java.util.ArrayList; public class ExampleIterator { public static void main(String args[]){ ArrayListanimal = new ArrayList (); animal.add("Horse"); animal.add("Lion"); animal.add("Tiger"); for(String animalObj : animal) { System.out.println(animalObj); } } }
Output:
Horse
Lion
Tiger
Look how simple it is. There is no reference to the Iterator explicitly since we are using for-each of generics.
To make an object iterable it needs to emit an Iterator object. To enforce this contract, Iterator interface is to be used. It contains a method named iterator() and it returns Iterator. Hence, any class that implements Iterable will return an Iterator.
public interface Collection<E> extends Iterable<E> {
For example take any Collection. A Collection is an interface that represents container for series of elements. Every collections like ArrayList, Vector implements Collection and so Iterator.
ListIterator an even better Iterator for a List containing more utility methods like getting index of elements and adding elements to the base object. Using ListIterator we can iterate in both the directions.
Look at the following code, it throws ConcurrentModificationException. We cannot add or remove elements to the underlying collection when we are using an iterator.
package com.javapapers; import java.util.ArrayList; public class ExampleIterator { public static void main(String args[]){ ArrayListanimal = new ArrayList (); animal.add("Horse"); animal.add("Lion"); animal.add("Tiger"); for(String animalObj : animal) { System.out.println(animalObj); animal.add("Hyena"); } } } Output: Horse Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at com.javapapers.ExampleIterator.main(ExampleIterator.java:13)
We will create our own custom class and make it implement Iterable, so that it returns an Iterator using which we can iterate the elements.
package com.javapapers; import java.util.ArrayList; import java.util.Iterator; public class AnimalIterator<String> implements Iterator<Object> { private ArrayList<?> animal; private int position; public AnimalIterator(Animal animalBase) { this.animal = animalBase.getAnimal(); } @Override public boolean hasNext() { if (position < animal.size()) return true; else return false; } @Override public Object next() { Object aniObj = animal.get(position); position++; return aniObj; } @Override public void remove() { animal.remove(position); } }
package com.javapapers; import java.util.ArrayList; import java.util.Iterator; public class Animal implements Iterable<String> { private ArrayList<String> animal = new ArrayList<String>(); public Animal(ArrayList animal){ this.animal = animal; } public ArrayList getAnimal() { return animal; } @Override public Iterator<String> iterator() { return new AnimalIterator(this); } }
package com.javapapers; import java.util.ArrayList; public class TestIterator { public static void main(String args[]) { ArrayList<String> animalList = new ArrayList(); animalList.add("Horse"); animalList.add("Lion"); animalList.add("Tiger"); Animal animal = new Animal(animalList); for (String animalObj : animal) { System.out.println(animalObj); } } }
Output:
Horse
Lion
Tiger
Comments are closed for "Java Iterator".
It’s nice and it’s easy to understand for beginners…
Thanks Joe. It was deep knowledge sharing.
Nice and easy,Thanks Joe
I always get to learn something new when read these articles..!! Thanks Joe..!!
Thanks
Very Nice Tutorial Joe.
Simple and elegant
Very good stuff
Nice — a good intro.
A few potentially confusing points:
– Having a class called “Animal” which actually represents a list-of-stuff is a big confusion. Maybe call it `class Zoo`, with a method `getAnimals()` (plural)?
– “AnimalIterator implements Iterator”
– ArrayList –> ArrayList, and Animal#getAnimal should return List.
– Replace each ‘ArrayList’ with ‘List’ unless it’s preceded with ‘new’.
– More heavyweight than you’d like for a tutorial perhaps, but your `next` method should really check and throw NoSuchElementException [rather than internally hitting an index-out-of-bounds exception that it relays along, revealing details about the class’s implementation)]:
`if (!this.hasNext()) throw new NoSuchElementException();`
(Whoops, all the angle-brackets got swallowed from my previous post. I’ll try `<` and `>`; if they get swallowed too replace them with less-than, greater-than of course.)
…
– “AnimalIterator<String> implements Iterator<String>”
– ArrayList<?> –> ArrayList<String>, and Animal#getAnimal should return List<String>.
…
Oh: AnimalIterator#delete has a bug; you delete the *next* item-to-be-returned, but it’s supposed to return the most-recently-returned item.
…More subtly, since you’re sharing the backing list between different iterators, surprising behavior can occur. For a tutorial, it’s probably best to have `remove` throw an unsupported-operation exception [for the same reasons that the Java designers had ArrayList iterators throw a ConcurrentModificationException].
…Hmm, now that I think about it, even the following code causes problems, w/ `remove`:
List<String> stuff = new ArrayList<String>();
stuff.add(“zebra”);
for ( String anim : new Animal(stuff) ) {
System.out.println( anim );
stuff.add(0,”a tribble”);
}
This will keep enumerating over the zebra, even though there is only one zebra in the list! (We keep inserting at 0, pushing the zebra over.) Dang mutation! The easiest fix is to have the iterator keep it’s own private, unmodifiable copy of the list:
public AnimalIterator(Animal animalBase) {
this.animal =
Collections.unmodifiableList(
animalBase.getAnimal()
);
}
Barland, appreciate your valuable comments. Thanks a lot. I will fix them immediately.
Nice…….
It is very much comprehensive
Well and simple to understand. Thanks.
is:
public boolean hasNext() {
if (position < animal.size())
return true;
else
return false;
}
should be:
public boolean hasNext() {
return position < animal.size();
}
btw. nice article :)
Hi,
Firstly thanks for this tutorial.
but I am getting confused about the “java.util.ConcurrentModificationException”.
If we can not add or remove elements from Iterator object then why this methods inside the Iterator.
please help me on this.
Good job sir…thank you
article is so useful and easy to understand.
Hi Joe,
I read your blogs usually. Even though you write for Java basics, all are interesting…
Also, private inner classes are usually the best way to go when doing something like this as this code is highly coupled with the Animal Class and cannot be reused elsewhere.
Example off the web:
[code]
class DataStructure implements Iterable<DataStructure> {
@Override
public Iterator<DataStructure> iterator() {
return new InnerEvenIterator();
}
// …
private class InnerEvenIterator implements Iterator<DataStructure> {
// …
public boolean hasNext() { // Why public?
// …
return false;
}
@Override
public DataStructure next() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
public static void main(String[] ex) {
DataStructure ds = new DataStructure();
Iterator<DataStructure> ids = ds.iterator();
ids.hasNext(); // accessable
}
}
[/code]
Thank You
every think is easy understandable.
Very Nice article joe keep it up!!!
Good to see this Article…Thank u
Joe, have started following your blog today and let me tell you that I haven’t left the site from last couple of hours
Really Good Stuff :)
Hi joe very nice site for java Lerner
Very Nice
Very good intro. Now I understand how work iterators.
Very nice article joe. Thanks you
Explained the concepts in easy term and very elegant web page degign. ListIterator can be used if we want to iterate forword and backward.
Its really a good and easy Blog
its nice and what is generics in java
Thank you ..
Its clear explanation..
Thanks again.
Hi Joe,
I like ur blog.Its written in simple language which can be easily understandable by the beginner.But there are very few topics that are covered in J2EE( i.e only jsp n servlets).I hope to see web services,EJB, STRUTS,HIBERNATE,SPRING framework in ur blog very soon.Great work.
@Shanthi,
thanks a lot. Quite soon I am starting on Struts, Spring and Hibernate. Stay tuned.
[…] and returns event objects. These are events for element, text, comment etc. This is similar to the java iterator in collections. Main interfaces in iterator api are XMLEventReader and XMLEventWriter. Base of the […]
@Biswa
Good Explanation
hi Joe,
your blogs are very much useful to me.
i want to know the difference between comparator and comparable interface.
and also where to use it?
pls help me Joe
Thanks for ur valuable info.. I am fresher in Spring framework so can u plz provide me material for learning Spring well…
Joe your doing very good job…and your giving very good information to learn java very easy to understand keep it up!!! You can prepare java interview questions….Thank you
Hi Joe, I need a program for display duplicates in the arraylist.If i have two arraylists li and li1,one arraylist having values like li.add(id=1,name,age);
li.add(id=3,name,age);
Another Arraylist having values like
li1.add(id=1);
li1.add(id=2);
li1.add(id=3);
.
.
.
……….etc
Now print the duplicate values from both arraylists in (i+j) iterations.
Condition is:
1.only (i+j) iterations perform
2.don’t use contains method
3.we can use map or other collections methods.
i need this joe.
Thanks a lot for making it so simple
Thanks it’s good for freshers
thanks…useful!!!!
Thanks,this post gave clear idea on iterating.But where is the iterator() method overridden.
Awesome. Good examples and explanations ..
Thank you. Its very useful..!!!
Yes.. Its very useful but Please tell me how to iterate Map Inferface.
[…] Java iterator provides us with interface to parse the items of the underlying collection. When we are using the iterator the underlying collection should not be modified. If this treaty is not honoured and it is possible in a multi-threaded environment, then we get a ConcurrentModificationException. […]
I couldn’t undestand your custom iterator
in TestIterator class you write only
Animal animal = new Animal(animalList);
for (String animalObj : animal) {
System.out.println(animalObj);
}
you never call the method hasNext(),next(),remove() of AnimalIterator class .How it is custom without AnimalIterator class we can do the same.Can u clear my dought?
Nicely Explained….
Good work thank you boss ….
Superb,Joe..
very useful
You have explained every design pattern so nicely that it make print in the memory.
It’s unfortunate that you’ve failed to implement the Iterator contract as required by the Iterator interface: http://docs.oracle.com/javase/6/docs/api/java/util/Iterator.html
Specifically your next() method throws the wrong exception if it’s called too many times and your implementation of remove() is completely wrong: it removes the wrong element, makes no attempt to check on if next() was called, and allows multiple calls at once.
This is a very poor example of implementing an interface.
Can you tell me how can i get to the start of the iterable after I have traversed it once. Need this very urgently. Please help.
Thank you joe..
Can you please explain equals() and hashcode() in HashMap?..
Hi,
Very nicely explained. How can we deal with following problem, Collection<Collection> have something like this and we need to implement the Iterator on the class that take this collection in constructor?
How to implement hasNext and next() to get all the elements in the nested collection.
Thanks.
what is the implementation class for Iterator?
the values of HashMap is retrieved based on the keys…. In general at the place of adding values we wo’t retrieve those values.. for example we add Objects(any type)to List in Dao layer,but we need to retrieve them in the Presentation Layer…..In this case although we pass the same key(at the time of adding) we won’t get the value back… This is because of we are using hashCode() method of Object class which generates based on the address but not based on the content that object consists of… for this reason we must override hashCode() in our class while adding that class objects to HasMap keys…
if we override hashCode() method at any time,it is must to override equals() method too…
Reason: According to java if two objects are giving the same hashcode value,then those two objects must be same.. to satisfy this condition if we override hashCode() method in our class then it is better to override equals() method also to avoid future problems..
i too accept
[…] Enumeration to iterate through the collections and from Java version 1.2 Iterator took its place. Java Iterator is a nice implementation of iterator design pattern allowing us to traverse through a collection in […]
Hello,
something in the following lines wrong:
“To make an object iterable it needs to emit an Iterator object. To enforce this contract, Iterator interface is to be used. It contains a method named iterator() and it returns Iterator. ”
It follows that Iterator interface has method iterator(), but Iterator interface has not a method called iterator().
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList al = new ArrayList();
al.add(“test”);
al.add(“test1”);
for(String str : al) {
al.remove(0);
System.out.println(str);
}
}
What about the above code.you mention we can not remove the element while iterating the collection but i did not get ConcurrentModificationException when i executed above code.
My idea: about this we cannot add elements while iterating the collection.
Reason: if we try to add, loop(Enhance Loop) will never terminate. I think so if any other reason please let us know.
excellent way of explaining
Thanks Joe! Nice Post with good example .
Very helpful. Thanks!
@Omeron Subda :
I think you are getting confused between Iterator and Iterable Interfaces.
Iterable interface has a method named iterator() which return an object of Iterator
I think you are getting confused between Iterator and Iterable Interfaces.
Iterable interface has a method named iterator() which return an object of Iterator
Very nice post. I just stumbled upon your blog and wished to say that
I’ve really enjoyed surfing around your blog posts. In any case I will be subscribing to your feed and I hope you write again soon!
nice explanation
Sir,Can you please answer this question for me .It was asked to me in one of my recent interviews:
Why add() method is declared in ListIterator and not on Iterator.
Sir, I really appreciate this blog as it gives deep insight into the concept.
While writing the above code in my way i confronted with some Error which i am not able to sort out. Please take a look in the problem
import java.util.ArrayList;
import java.util.Iterator;
class typeAnimal implements Iterable //// <————– (1)
{
ArrayList listAnimal = new ArrayList();
typeAnimal(ArrayList listAnimal)
{
this.listAnimal = listAnimal;
}
@Override
public Iterator iterator()
{
return new Iterator()
{
int position;
@Override
public boolean hasNext() {
if(position<listAnimal.size())
return true;
else
return false;
}
@Override
public String next()
{
String aniPos = listAnimal.get(position);
position ++;
return aniPos;
}
@Override
public void remove() {
// TODO Auto-generated method stub
}
};
}
}
public class newIterator
{
public static void main(String[] args)
{
ArrayList animalList = new ArrayList();
animalList.add(“priyank”);
animalList.add(“kannu”);
typeAnimal animalName= new typeAnimal(animalList);
for(String name:animalName) //// <– Error: Type mismatch: cannot convert from element
type Object to String
{
System.out.println(name);
}
}
}
if i replace typeAnimal with typeAnimal the Error will go away. What exactly causing this Error and why with little change the Error is going away.
Please help me with this problem
Thanks