3

At Oracle tutorial about collections https://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html I see the following:

Use Iterator instead of the for-each construct when you need to:

1. Remove the current element. The for-each construct hides the iterator, so you cannot call remove. Therefore, the for-each construct is not usable for filtering.
2. Iterate over multiple collections in parallel.

I understand the first option 'remove current element' which is supported by iterator and not supported by for-each construct. I need clarification about the second option 'iterate over multiple collections in parallel' which can be done with iterator and not by for-each. can someone supply an example of such scenario? As far as I understand the for-each can also be nested, so one can travel on several collections in parallel.

This is not duplicate of Iterator vs For-Each and of Iterator vs for as they ask about general comparison of iterator and for-each, and I ask about the specific sentence at oracle tutorial.

Eliyahu Machluf
  • 1,251
  • 8
  • 17
  • 4
    maybe something like this: `while(iter1.hasNext() && iter2.hasNext()){ ... }` which would not be possible with an enhanced for-loop – Lino Jan 14 '19 at 13:06
  • *"for-each can also be nested, so one can travel on several collections in parallel"* That is not iterate-in-parallel. That is iterating second collection in full for each element of first collection. Iterate-in-parallel means to process first element from both together, then second element from both together, then third element, and so forth. If the collections are not the same size, the extra elements from the larger collection may or may not be processed, as deemed necessary by the purpose of the loop. – Andreas Jan 14 '19 at 13:25

2 Answers2

8

Suppose you have two collections:

List<A> listA = /*...*/;
List<B> listB = /*...*/;

...and you need to iterate through them in parallel (that is, process the first entry in each, then process the next entry in each, etc.) You can't do that with the enhanced for loop, you'd use Iterators:

Iterator<A> itA = listA.iterator();
Iterator<B> itB = listB.iterator();
while (itA.hasNext() && itB.hasNext()) {
    A nextA = itA.next();
    B nextB = itB.next();
    // ...do something with them...
}

To be fair, you could combine an enhanced for loop with an iterator:

Iterator<A> itA = listA.iterator();
for (B nextB : listB) {
    if (!itA.hasNext()) {
        break;
    }
    A nextA = itA.next();
    // ...do something with them...
}

...but it's clumsy and clarity suffers, only one of the collections can be the subject of the for, the rest have to be Iterators.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

As far as I understand the for-each can also be nested, so one can travel on several collections in parallel.

By nesting for-each we cann't travel multiple collections in parallel.

List<A> listA = /*...*/;
List<B> listB = /*...*/;

for(A a:listA){
    for(B b:listB){
        //do something
    }
}

Above code cann't achieve travel on several collections in parallel but iterating second collection in full for each element of first collection.

And something like for(A:listA;B:listB) doesn't compile in Java.


Note that besides Iterator, we can also use the traditional for loop:

for(int i=0,min=Math.min(listA.size(),listB.size());i<min;i++){
    // ...do something with them...
}
ZhaoGang
  • 4,491
  • 1
  • 27
  • 39
  • 1
    This may be better than your last example `for(int i=0, min = Math.min(listA.size(), listB.size()) ; i < min ; i++)` as the size method will only be executed once – Lino Jan 14 '19 at 13:59