Monday, February 7, 2011

How does the Java for each loop work?

List<String> someList = new ArrayList<String>()
// add "monkey", "donkey", "skeleton key" to someList
for(String item : someList ){
   System.out.println(item);
}

What would the equivalent for loop look like without using the for each syntax?

  • for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {
      String item = i.next();
      System.out.println(item);
    }
    

    Note that if you need to use i.remove(); in your loop, or access the actual iterator in some way, you cannot use the for( : ) idiom, since the actual Iterator is merely inferred.

    As was noted by Denis Bueno, this code works for any object that implements the Iterable interface.

    Also, if the right-hand side of the for(:) idiom is an array rather than an Iterable object, the internal code uses an int index counter and checks against array.length instead. See http://forums.sun.com/thread.jspa?messageID=2743233

    From nsayer
  • The for-each loop in java uses the underlying iterator mechanism. So it's identical to the following:

    Iterator<String> iterator = someList.iterator();
    
    while (iterator.hasNext()) {
      String item = iterator.next();
      System.out.println(item);
    }
    
    From toluju
  • Check here

    From jb
  • Here's an equivalent expression.

    for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
        System.out.println(sit.next());
    }
    
    From Hank
  • It would look something like this. Very crufty.

    for (Iterator<String> i = someList.iterator(); i.hasNext(); )
            System.out.println(i.next());
    

    There is a good writeup on for each in the Sun documentation.

    From Pete
  • for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
    String item = itr.next();
    System.out.println(item);
    }

  • It's implied by nsayer's answer, but it's worth noting that the OPs for(..) syntax will work when "someList" is anything that implements java.lang.Iterable -- it doesn't have to be a list, or some collection from java.util. Even your own types, therefore, can be used with this syntax.

    fd : Also, by some cunning magic object arrays also work.
    nsayer : fd is right - the internal code when the right-hand side of the for(:) idiom uses an int and array.length instead of fetching an Iterator. http://forums.sun.com/thread.jspa?messageID=2743233
  • Also note that using the "foreach" method in the original question does have some limitations, such as not being able to remove items from the list during the iteration.

    The new for-loop is easier to read and removes the need for a separate iterator, but is only really usable in read-only iteration passes.

    From Bill James
  • @rtf

    It isn't by index, as not everything that implements Iterable is a list. It could be a set or map or anything else that implements iterable.

  • Since I can't edit/comment, here is my addition.

    for each is also valid for arrays. e.g.

    int[] test = new int[]{1,4,5,7};
    for (int intValue : test) {
        // do some work here on intValue
    }
    

    So, overall summary:
    [nsayer]The following is the longer form of what is happening:

    for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {
      String item = i.next();
      System.out.println(item);
    }
    

    Note that if you need to use i.remove(); in your loop, or access the actual iterator in some way, you cannot use the for( : ) idiom, since the actual Iterator is merely inferred.

    [Denis Bueno]

    It's implied by nsayer's answer, but it's worth noting that the OPs for(..) syntax will work when "someList" is anything that implements java.lang.Iterable -- it doesn't have to be a list, or some collection from java.util. Even your own types, therefore, can be used with this syntax.

    Answer to Konrad Rudolph's comment

    1. To collect together all the relevant information in one place so there's one comprehensive answer (isn't that the point of SO?)
    2. ADD the fact that it also applies to arrays (which wasn't mentioned previously at the time of my posting.)
    3. Because I don't have the rep to edit someone else's post to add my thoughts or add a comment to mention that it works on arrays.
    Konrad Rudolph : Hmm, what was the point in repeating all the information?
    From Mikezx6r
  • The Java "for-each" loop construct will allow iteration over two types of objects:

    • T[] (arrays of any type)
    • java.lang.Iterable<T>

    The Iterable<T> interface has only one method: Iterator<T> iterator(). This works on objects of type Collection<T> because the Collection<T> interface extends Iterable<T>.

0 comments:

Post a Comment