迭代列表的最佳方法是什么

What is the best way to iterate over list

我在 collection 方面做了很多工作,但我几乎没有怀疑。

我知道我们可以用迭代器迭代列表。

另一种方法是我们可以通过以下方式:

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

我认为这里存在一个问题,即每次调用 list.size() 时都会构建影响性能的整棵树。

我认为还有其他解决方案:

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

我觉得这样可以解决问题。我不太接触线程。我在想这是否应该是正确的做法。

我认为的另一种方式是:

for (Object obj; list){

}

有了这个新的 for 循环,我想编译器会再次检查列表的大小。

请从这些或其他性能高效的方法中提供最佳解决方案。谢谢你的帮助。

在每次迭代时调用 size() 并不是真正的问题。对于我所知道的所有集合,此操作的复杂度为 O(1):size() 只是 returns 列表字段的值,保持其大小。

第一种方式的主要问题是对get(i)的重复调用。此操作对于 ArrayList 是 O(1),但对于 LinkedList 是 O(n),使得整个迭代 O(n2) 而不是 O(n):get(i) 强制列表从列表的第一个元素(或最后一个)开始,并转到下一个节点,直到第 i 个元素。

使用迭代器,或使用 foreach 循环(在内部使用迭代器),保证使用最合适的迭代方式,因为迭代器知道列表是如何实现的,以及如何最好地从一个元素开始到下一个。

顺便说一句,这也是迭代非索引集合(如 Sets)的唯一方法。所以你最好习惯使用那种循环。

对于你的例子来说最好的方法是:

for (Object obj: list){

}

与 java 版本 < 1.5 相同:

for (Iterator it = hs.iterator() ; it.hasNext() ; ){}

它使用集合的迭代器。您实际上不需要集合的大小。 .size() 方法实际上不应该构建树,但是 .get() 可以循环到给定的元素。 .get() 和 .size() 方法取决于 List 实现。 ArrayList 中的 .get() 实际上应该是 O(1) 复杂度而不是 O(n)

更新

在java8中你可以使用:

myList.forEach{ Object elem -> 
 //do something
}

在性能方面迭代列表的最佳方法是使用迭代器(第二种方法是使用 foreach )。 如果您使用 list.get(i),它的性能将取决于列表的实现。对于 ArrayList,list.get(i) 是 O(1),而对于 LinkedList 是 O(n)。

此外,list.size() 是 O(1) 并且不应对性能产生任何影响。

for (Object obj: list){

}

上面的代码对我来说是最好的方法,它很干净并且易于阅读。

Java8 中的 forEach 也不错。