For Each循环问题

3

我有困难理解for-each循环。我熟悉典型的for-each结构,其中有内置计数器和分配语句到每个元素。然而,在下面的代码中,“new”关键字意味着什么?它只执行一次吗?

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

这是否等同于以下的for循环?
for(int ctr = 0; ctr < myCollection.size(); ctr++){
    Integer temp = myCollection.get(ctr);
    myCollection.add(first.intValue() + item.intValue());
}

我假设你想要的是 first.intValue() 而不是 first,intValue()。 - Peter Lawrey
有没有人提到过 LinkedList<> myCollection 的 O(n^2)? - Tom Hawtin - tackline
5个回答

4
< p > new 关键字意味着它将创建一个新的ArrayList,就像在代码中的任何其他地方一样。

代码基本上与以下代码相同。在for-each循环中使用new没有什么特别之处。

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

这与您的替代循环不同,因为当您向其中添加内容时,size()会发生变化。我假设您打算让 ctri 相同。它相当于:

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

我想这与

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

2
第一个代码块创建了一个新的ArrayList,其中包含Integers,将myCollection的内容复制到其中,然后遍历结果ArrayList
由于循环内部修改了原始的myCollection,因此需要进行复制。
第二个代码块与第一个代码块不同,因为它在迭代myCollection时添加元素。由于这种交互作用,它不会按照您的预期执行,并将导致无限循环。

严谨地说,一个ArrayList只能有2^31-1个元素,而不是进入无限循环。实际上,当它尝试增长到超过这个数量的元素时,它会在大约14亿处停止。;) 如果您使用LinkedList,则会在Integer.MAX_VALUE处停止,因为这是size()可以返回的最大值。 - Peter Lawrey

0
你提供的两个代码非常相似,但主要区别(即那里的new关键字)在于第一个代码中你正在创建原始列表的副本。这是必需的,因为在循环内部,你正在向列表添加更多项,增加其大小。这样,循环将永远不会退出,并最终会耗尽内存。
使用for(;;)的等效代码如下:
List<Integer> auxList = new ArrayList<Integer>(myCollection);
for(int ctr = 0; ctr < auxList.size(); ctr++){
    myCollection.add(first.intValue() + auxList.get(ctr));
}

或者你可以预先计算大小以避免这个验证码:

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

除此之外,唯一的区别是foreach方法使用迭代器而不是通过索引访问元素。

希望能有所帮助!


0

它只执行一次吗?

是的。

这是否等同于以下for循环?

不是。你的循环有以下三个错误:

  1. first,intValue(),循环索引是ctr但是myCollection.get(i),你将其提取到temp中并留下未定义的item
  2. 迭代myCollection,同时添加到它,而不断检查与不断增长的大小进行比较,因此它
  3. 不会终止(size()正在增长),除非它
  4. 最终会抛出OutOfMemoryError

然而,它等同于这个:

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

0

你的for循环

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

被编译成相同的代码(除了变量名)

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

如果myCollection的大小不会改变(并且myCollection是一个List),那么这将与以下代码相同(只是创建临时列表的效率较低):
for(int ctr = 0; ctr < myCollection.size(); ctr++){
    Integer temp = myCollection.get(i);
    myCollection.add(first.intValue() + temp.intValue());
}

...但是你在循环内部改变了myCollection,所以第二个循环永远不会结束(假设至少有一个元素在其中)。

因此,你的ArrayList有助于使你的循环表现良好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接