2

Iterator is guaranteed to have the following methods:

  • hasNext()
  • next()
  • remove (optional)

When for-each loop iterates through iterable class objects, how does it know what object to start with? The above methods provide clear path forward, but what points to the starting element?

For-each guarantees to iterate through all relevant objects. Depending on a class and its next() implementation it could be vitally important where to start (consider forward linked list or any other implementation that has a root element).

How does it work?

If my question does not make sense please explain why.

PM 77-1
  • 12,933
  • 21
  • 68
  • 111
  • It uses whatever `next()` returns on the first iteration... – Oliver Charlesworth Sep 24 '13 at 22:49
  • The iterator you obtain from the container is initialized to the start. – andy256 Sep 24 '13 at 22:50
  • You define where to start in the `Iterator` implementation. For example, for `List`s, you have a *straight* iterator that goes from first element to last, and a reverse iterator that goes from last element to first. – Luiggi Mendoza Sep 24 '13 at 22:52
  • @LuiggiMendoza - What about my **own custom iterator**? Where exactly the starting point logic should be implemented? Like in [another question](http://stackoverflow.com/questions/18992132/how-to-make-a-class-which-is-not-a-descendant-of-collection-compatible-with) you were helping me with. – PM 77-1 Sep 25 '13 at 02:16
  • In that case, your iterator will start with the first `Thing` you can access. Then, it depends how you want to navigate through that tree. As noted in comments, you can implement prefix, infix or postfix traversal. – Luiggi Mendoza Sep 25 '13 at 02:21
  • @LuiggiMendoza - I'm very sorry for being so thick, but I am still not sure that I got it. Do I need to preserve the `root` (in my case `Thing` with `null` *previous* variable) object myself and make sure that iterator method returns iterator instance that points to this root? – PM 77-1 Sep 25 '13 at 02:31
  • This depends on the implementation. As I've posted in comments, you can do this using a `Queue`or another data structure to do the navigation before. – Luiggi Mendoza Sep 25 '13 at 02:40

4 Answers4

2

You might want to look at ArrayList's implementation of an Iterator, the Itr inner class.

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }
    ...
}

cursor gets initialized to 0 by default. You use cursor to access the elements in the ArrayList object's backing array (it's an inner class, it has access to that field).

Similar logic applies for other implementations of Iterator. It always depends on the underlying data structure. As another example, a Set is not supposed to have an ordering, but it does implement Iterator. A decision has to be made as to where the iterator starts.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
2

From the spec:

What's officially called the enhanced for statement (for(E e: Iterable<E> iterable)) is translated by the compiler into the equivalent of the following code:

E e;
for(Iterator<E> it = iterable.iterator(); it.hasNext(); ) {
    e = it.next();
    // contents of your for loop
}

The behavior of the loop is exactly as if you'd written it with an explicit Iterator, so the "starting point" of the enhanced for loop is wherever iterable.iterator() would have started anyway.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
0

foreach is a shorthand for for loop starting from first till last.

Abhijith Nagarajan
  • 3,865
  • 18
  • 23
  • What defines "*first*" and "*last*" for custom class that is **not** derived from Java `Collection`? – PM 77-1 Sep 25 '13 at 02:09
0

This all depends on your collection.

If your collection is a List (ArrayList or LinkedList usually), then the iterator will go in list order according to how they were inserted.

If it is a Map or Set, it is very hard to predict the ordering of its members. If you are using a Map or Set, you should not count on any sort of predictable ordering, in fact, because it doesn't match those collections' purposes. However, LinkedHashMap or LinkedHashSet can be used if you need a specific order but also need the functionality of a Map or Set.

Mar
  • 7,765
  • 9
  • 48
  • 82