2

我知道使用 LinkedList 迭代

for(int i = 0; i < list.size(); i++){
  Item item = list.get(i);
}

获取单个对象的性能很差,因为每次调用 .get(i) 都会从列表的开头迭代到 i。

正确的方法是使用迭代器。到目前为止,一切都很好。

但是这种风格呢:

for(Item item : list){
  // item is already here
}

这是否具有与使用迭代器相同的性能?这在内部如何运作?

4

3 回答 3

3

这是否具有与使用迭代器相同的性能?

是的。两种变体都生成相同的字节码。以下字节码是从 for-each 循环生成的,但在循环中使用迭代器时,它看起来完全相同:

for(Object o : list) {
}

  44: aload_1
  45: invokevirtual #30                 // Method java/util/LinkedList.iterator:()Ljava/util/Iterator;
  48: astore_3
  49: goto          59
  52: aload_3
  53: invokeinterface #34,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
  58: astore_2
  59: aload_3
  60: invokeinterface #40,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
  65: ifne          52

这在内部如何运作?

在非数组的情况下,for-each 循环在内部使用迭代器。请参阅上面的字节码 - 调用所有方法,在使用迭代器时也会调用这些方法。

另请参阅For-Each 循环Java 'for each' 循环如何工作?了解更多信息。

于 2013-02-23T19:20:49.077 回答
2

foreach循环使用接口Iterable。它调用iterator()并使用迭代器进行迭代。对数组使用特殊处理。

于 2013-02-23T19:20:49.717 回答
0

一个区别是当您不想更改size列表时使用每个循环。因为它使用iteratorswhich 成为列表invalidate之后resize。而在正常的 for 循环中不是这种情况。但是每次standard loop调用size函数都会降低效率for each。要获得两者相同的性能,您需要将constant10,15,..etc 等值置于standard loop.

  • For Each -- 只读模式

  • 标准——读写两者

具体到问题:标准 for 循环确实效率低下,因为每次get从头开始调用时都必须遍历列表。这比调用size

于 2013-02-23T19:23:21.073 回答