迭代链表的差异

时间:2013-02-23 19:17:51

标签: java

我知道使用

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

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

正确的方法是使用Iterator。到现在为止还挺好。

但是这种风格怎么样:

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

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

3 个答案:

答案 0 :(得分:3)

  

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

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

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-loop在内部使用Iterators。请参阅上面的字节代码 - 调用所有方法,这些方法在使用迭代器时也会被调用。

另请参阅The For-Each LoopHow does the Java 'for each' loop work?以获取更多信息。

答案 1 :(得分:2)

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

答案 2 :(得分:0)

当您不想更改列表的size时,每个循环都有一个区别。因为它使用的iterators在列表的invalidate之后变为resize。这不是正常for循环的情况。但是standard loop会调用size函数每次使其效率低于for each。要获得两者的相同性能,您需要将constant值设置为10,15,...等standard loop的条件。

  • For Each - 只读模式

  • 标准用于 - 读写两者

特定于问题:循环的标准效率非常低,因为每次从头开始调用get时都必须遍历列表。这比调用size <更有问题/ p>