迭代列表的最佳方法是什么
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 也不错。
我在 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 也不错。