如果有的话,下面两个循环之间的性能差异是什么?

for (Object o: objectArrayList) {
    o.DoSomething();
}

and

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

当前回答

Accepted answer回答了这个问题,除了ArrayList…

因为大多数开发人员都依赖于ArrayList(至少我是这么认为的)

所以我有义务在这里加上正确答案。

直接从开发人员文档:-

增强的for循环(有时也称为“for-each”循环)可用于实现Iterable接口的集合和数组。对于集合,会分配一个迭代器来对hasNext()和next()进行接口调用。使用ArrayList,手工编写的计数循环大约快3倍(有或没有JIT),但对于其他集合,增强的for循环语法将完全等同于显式迭代器的使用。

有几种迭代数组的方法:

static class Foo {
    int mSplat;
}

Foo[] mArray = ...

public void zero() {
    int sum = 0;
    for (int i = 0; i < mArray.length; ++i) {
        sum += mArray[i].mSplat;
    }
}

public void one() {
    int sum = 0;
    Foo[] localArray = mArray;
    int len = localArray.length;

    for (int i = 0; i < len; ++i) {
        sum += localArray[i].mSplat;
    }
}

public void two() {
    int sum = 0;
    for (Foo a : mArray) {
        sum += a.mSplat;
    }
}

zero()是最慢的,因为JIT还不能优化掉每次循环迭代获取数组长度的成本。

一个()比较快。它将所有内容提取到局部变量中,避免了查找。只有数组长度能带来性能上的好处。

two()对于没有JIT的设备来说是最快的,对于有JIT的设备来说与one()是没有区别的。它使用Java编程语言1.5版中引入的增强for循环语法。

因此,默认情况下您应该使用增强的for循环,但是可以考虑使用手写的计数循环来进行性能关键的ArrayList迭代。

其他回答

1. for(Object o: objectArrayList){
    o.DoSomthing();
}
and

2. for(int i=0; i<objectArrayList.size(); i++){
    objectArrayList.get(i).DoSomthing();
}

两者都做同样的事情,但为了方便和安全的编程使用,在第二种使用方式中有容易出错的可能性。

Foreach使你的代码的意图更清晰,这通常比非常小的速度改进更受欢迎——如果有的话。

每当我看到一个索引循环,我必须解析它一段时间,以确保它做什么,我认为它做,例如,它是否从零开始,它是否包括或排除终点等?

我的大部分时间似乎都花在了阅读代码(我写的或别人写的)上,而清晰度几乎总是比性能更重要。现在很容易忽略Hotspot的性能,因为Hotspot做得非常出色。

对性能的影响基本上是微不足道的,但也不是零。如果你看看JavaDoc的RandomAccess接口:

根据经验,一个列表 实现应该实现这个 的典型实例 这个类,这个循环: For (int i=0, n=list.size();I < n;我+ +) list.get(我); 运行速度比这个循环快: for(迭代器i=list.iterator();i.hasNext (); i.next ();

for-each循环使用version with iterator,以ArrayList为例,for-each循环不是最快的。

通过变量名称objectArrayList,我假设它是java.util.ArrayList的一个实例。在这种情况下,性能差异是不明显的。

另一方面,如果它是java.util的实例。LinkedList,第二种方法会慢得多,因为list# get(int)是一个O(n)操作。

因此,第一种方法总是首选的,除非循环中的逻辑需要索引。

使用迭代器总是比使用索引更好。这是因为iterator最有可能针对List实现进行了优化,而索引(调用get)可能没有。例如,LinkedList是一个List,但是通过它的元素建立索引将比使用迭代器迭代慢。