Friday, February 25, 2011

Java Iterator - Best practices


In a recent code review at WSO2, Afkham Azeez mentioned some java best practices. This was something I didn't knew before. There are two ways to use a java iterator. One method is using a While-loop. The other way is to use For-loop. But the first method can drive you into errors if not correctly handled. Look at the following code.
List<String> list = new ArrayList<String>();
    list.add("1");
    list.add("2");
    list.add("3");

Iterator<String> iter = list.iterator();
    while ( iter.hasNext() ){
      System.out.println( iter.next() );
    }

System.out.println(iter.next());

If you see carefully, now the iterator can been used outside the while-loop and it might throw NoSuchElementException as iter.hasNext() is not called, in each iter.next() call.

By using a for-loop we can avoid this by restricting the iterator to be accessed only inside the for-loop scope.

eg -
List<String> list = new ArrayList<String>();
    list.add("1");
    list.add("2");
    list.add("3");

for ( Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
      System.out.println( iter.next() );
    }

5 comments:

Wouter Oet said...

Or just use for(String s : list) {}

Scott said...

As per Josh bloch's effective java, like 100 years ago

kohan said...

for me for(String s : list) {} it better and easy

javarevisited said...

Nice article , just to add the functionality of Enumeration interface is duplicated by the Iterator interface.
Iterator has a remove() method while Enumeration doesn't. Enumeration acts as Read-only interface, because it has the methods only to traverse and fetch the objects, where as using Iterator we can manipulate the objects also like adding and removing the objects.

to read more see here difference between iterator and enumeration

Michael Nishizawa said...

Effective Java has been updated to state that, when your code uses generics, use for-each notation. If you MUST use iterators(i.e. you are working on legacy code or (shudder) you are stuck in a 1.4- environment).

This code effectively demonstrates the pattern, but the addition of generics makes it a little confusing as to why someone would do this.