对于每个循环何时和何时不使用enhance/的限制



所以我对每个循环的介绍都有点爱恨交加的关系。有时,我认为它们的效用是无价的,可以迭代和ArrayList of Objects(等等),只是循环并调用给定对象类的方法。但是,我想知道使用for each的限制和最佳实践,而不是使用常规的for循环来遍历ArrayList或Array的每个元素。

没什么,这个问题是开放式的。如果有的话,我想看看处理每个特定循环结构时的最佳实践和用例是什么。

如果你正在迭代一个实现List接口的类,常规的for循环将使用List .get(I)获取下一个元素,for each将在内部使用Iterator并调用Iterator .next()。这对某些类的循环速度有很大的影响。

一个小例子:

LinkedList<Integer> list = new LinkedList<>();
for (int i = 0; i < 100_000; i++) list.add(i);
int doNothing = 0;
long start1 = System.nanoTime(), end1;
for (int i = 0; i < list.size(); i++) doNothing+= list.get(i);
end1 = System.nanoTime();
System.out.println(end1-start1);
doNothing = 0;
long start2 = System.nanoTime(), end2;
for(Integer i : list) doNothing+= i;
end2 = System.nanoTime();
System.out.println(end2-start2);

我的机器上的输出:

3460558170   //nanoseconds regular
2178261      //nanoseconds for each ~1000 times as fast in this specific example

for每个循环之所以快得多,是因为当它有第一个元素时,它直接跳到下一个元素并处理下一个节点。在LinkedList类中,每个插入的对象由一个记住下一个节点的节点表示。所以它在O(n)内执行。

foreach uses iterator
*
*
*
*
*

在一个普通循环中,当list.get(i)被调用时,它将从头开始,从节点跳到节点i次。当列表很长时,需要一些时间。当在循环中执行此操作时,性能在O(n²)内。

regular for list.get(i)
*
**
***
****
*****

有时你会遇到这样的情况,你只知道一个List - Interface是由一个方法调用返回的。如果它返回一个很长的LinkedList,而你使用一个正常的fori,对性能的影响可能是巨大的。

试试我发布的代码,并改变列表的长度来检查差异。

相关内容

  • 没有找到相关文章

最新更新