Java Iterator

18/03/2012

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:

  • We can iterate only in one direction
  • Iteration can be done only once. If you reach the end of series its done. If we need to iterate again we should get a new Iterator.

Iterator Example without Generics

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.

Ads by Google

Iterator Example using Generics

package com.javapapers;

import java.util.ArrayList;

public class ExampleIterator {

	public static void main(String args[]){
		ArrayList<String> animal = new ArrayList<String>();
		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.

Iterable and Iterator

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.

  • One advantage of Iterable is, when you implement Iterable then those object gets support for for:each loop syntax.

Removing elements using Iterator

  • Iterator has a remove method using which we can delete elements from the underlying object.
  • It removes the last element returned by the iterator.

Difference between Iterator and Enumeration interfaces

  1. remove() method is introduced in iterator. Using this method we can remove element from the underlying collection which we are iterating.
  2. Enumeration has two methods and both are available in iterator. Method names for both of them are shortened.

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.

ConcurrentModificationException

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[]){
		ArrayList<String> animal = new ArrayList<String>();
		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)

Implementing our own Custom Iterator

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

This Core Java tutorial was posted on 18/03/2012.
Ads by Google

78 comments on “Java Iterator

  1. It’s nice and it’s easy to understand for beginners…

  2. Thanks Joe. It was deep knowledge sharing.

  3. I always get to learn something new when read these articles..!! Thanks Joe..!!

  4. 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();`

  5. (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>.

  6. 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()
    );
    }

  7. Barland, appreciate your valuable comments. Thanks a lot. I will fix them immediately.

  8. 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 :)

  9. Clear and userfriendly Explanation!!

  10. Hi from my end,

    I liked your site: “javapapers.com”.
    Can we email about a proposition
    with your site? This is regarding a posting in your site.

    I can surely render certain benefits to you.

    Looking for your reply.

    Regards,
    Sudipto

  11. 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.

  12. Good job sir…thank you
    article is so useful and easy to understand.

  13. Hi Joe,
    I read your blogs usually. Even though you write for Java basics, all are interesting…

  14. 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.

  15. Example off the web:

    
    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            
        }
    }
    
    
  16. Thank You
    every think is easy understandable.

  17. 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 :)

  18. Explained the concepts in easy term and very elegant web page degign. ListIterator can be used if we want to iterate forword and backward.

  19. its nice and what is generics in java

  20. 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.

  21. @Shanthi,

    thanks a lot. Quite soon I am starting on Struts, Spring and Hibernate. Stay tuned.

  22. Pingback: Java StAX

  23. Good Explanation.U Did a greatejob…
    @chowdary

  24. 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

  25. Thanks for ur valuable info.. I am fresher in Spring framework so can u plz provide me material for learning Spring well…

  26. Joe your doing very good job…and your giving very good information to learn java very easy….&understanding also easy..keep it up…

  27. 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

  28. 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.

  29. 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.

  30. Thanks,this post gave clear idea on iterating.But where is the iterator() method overridden.

  31. Awesome. Good examples and explanations ..

  32. Yes.. Its very useful but Please tell me how to iterate Map Inferface.

  33. Pingback: Fail Fast vs Fail Safe

  34. Pingback: Fail Fast vs Fail Safe | My Blog

  35. 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?

  36. Nicely Explained….
    Good work thank you boss ….

  37. You have explained every design pattern so nicely that it make print in the memory.

  38. 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.

  39. 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.

  40. Thank you joe..
    Can you please explain equals() and hashcode() in HashMap?..

    • 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..

  41. 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.

  42. what is the implementation class for Iterator?

  43. Pingback: Iterator Design Pattern

  44. 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().

  45. 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.

  46. Thanks Joe! Nice Post with good example .

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>