gerky
gerky

Reputation: 6417

For Each Loop Question

I'm having problems understanding a for-each loop. I am familiar w/ the typical structure of a for-each, where there is built in counter and assignment statement to each element. However, in the code below what does the "new" keyword imply? Does it execute only once?

for(Integer item : new ArrayList<Integer>(myCollection)){
    myCollection.add(first.intValue() + item.intValue());
}

Is this equivalent to the following for loop?

for(int ctr = 0; ctr < myCollection.size(); ctr++){
    Integer temp = myCollection.get(ctr);
    myCollection.add(first.intValue() + item.intValue());
}

Upvotes: 3

Views: 418

Answers (5)

Paŭlo Ebermann
Paŭlo Ebermann

Reputation: 74750

Your for loop

for(Integer item : new ArrayList<Integer>(myCollection)){
    myCollection.add(first.intValue() + item.intValue());
}

is compiled to the same code (modulo variable names) as

for (Iterator<Integer> iterator = new ArrayList<Integer>(myCollection).iterator();
     it.hasNext(); ) {
    Integer item = iterator.next();
    myCollection.add(first.intValue() + item.intValue());
}

If the size of myCollection would not change (and myCollection is a List), then this would be the same (only less efficient for creating a temporary list) as

for(int ctr = 0; ctr < myCollection.size(); ctr++){
    Integer temp = myCollection.get(i);
    myCollection.add(first.intValue() + temp.intValue());
}

... but you are changing myCollection inside the loop, so this second loop would never reach the end (assuming at least one element is in it).

So your ArrayList helps having your loop well-behaved.

Upvotes: 0

rlibby
rlibby

Reputation: 6021

Does it execute only once?

Yes.

Is this equivalent to the following for loop?

No. Your loop that follows

  1. has three errors (first,intValue(), loop index is ctr but myCollection.get(i), you fetch into temp and leave item undefined),
  2. iterates over myCollection, adding to it, while continually checking against a growing size, and so it
  3. does not terminate (size() is growing), except that it
  4. will eventually throw an OutOfMemoryError.

It is, however, equivalent to this

for (int i = 0, n = myCollections.size(); i < n; i++) {
    Integer item = myCollection.get(i);
    myCollection.add(first.intValue() + item.intValue());
}

Upvotes: 0

redent84
redent84

Reputation: 19239

The two codes that you provide are very similar, but the main difference (the new keyword there) is that in the first code you are creating a copy of the original list. This is required because inside the loop, you are adding more items to the list, increasing its size. This way, the loop will never exit and eventually you will get of of memory.

The equivalent code using for(;;) would be the following:

List<Integer> auxList = new ArrayList<Integer>(myCollection);
for(int ctr = 0; ctr < auxList.size(); ctr++){
    myCollection.add(first.intValue() + auxList.get(ctr));
}

Alternatively you could simply precalculate the size to avoid this captcha:

int size = myCollection.size();
for(int ctr = 0; ctr < size; ctr++){
    myCollection.add(first.intValue() + myCollection.get(ctr));
}

Other than that, the only difference is that the foreach approach uses iterators instead of accessing elements by indexes.

Hope it helps!

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533472

The new key word implies that it will create a new ArrayList, as if it where anywhere else in code.

The code is basically the same as the following. There is nothing special about using new in a for-each loop.

List<Integer> list = new ArrayList<Integer>(myCollection);
for(Integer item : list){
    myCollection.add(first.intValue() + item.intValue());
}

It is not the same as your alternative loop as the size() changes when you add things to it. I assume you intended for ctr and i to be the same. It is equivalent to

for(int i = 0, size = myCollection.size(); i < size; i++){
    myCollection.add(first.intValue() + myCollection.get(i).intValue());
}

which I imagine is the same as

for(int i = 0, size = myCollection.size(); i < size; i++)
    myCollection.add(first + myCollection.get(i));

Upvotes: 4

NPE
NPE

Reputation: 500177

The first block of code creates a new ArrayList of Integers, copies the contents of myCollection into it, and then iterates over the resulting ArrayList.

The copy is needed since the original myCollection gets modified inside the loop.

The second block of code isn't equivalent to the first since it adds elements to myCollection while iterating over it. Because of this interaction it won't do what you expect and will result in an infinite loop.

Upvotes: 2

Related Questions