For Each Loop Question

核能气质少年 提交于 2019-12-21 20:48:59

问题


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());
}

回答1:


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));



回答2:


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.




回答3:


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!




回答4:


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());
}



回答5:


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.



来源:https://stackoverflow.com/questions/5315564/for-each-loop-question

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!