增强了循环

时间:2014-01-31 09:16:24

标签: java performance for-loop

我经常遇到一些情况,我希望使用一个强大的for循环来获取某些从某个对象获得的Collection或数组。

e.g。

items = basket.getItems();
for (int item : items) {
    // Do something
}

另一种方法是:

for (int item : basket.getItems()) {
    // Do something
}

第二个更紧凑,在我看来提高了可读性,特别是当item变量不会在其他任何地方使用时。

我想知道for语句中的getter是否对性能有任何影响。它会被优化到类似于第一个的东西吗?或者它每次都会访问吸气剂?当然,getItems()可能会做很慢的事情(例如网络访问等)

问题类似于其他问题,但是指的是集合/数组本身的getter而不是它的大小。但是,最终可能是相同的情况。

4 个答案:

答案 0 :(得分:9)

在两种情况下,getItems()方法只会被调用一次。除了使用额外的局部变量之外,两者之间没有区别。

正如您在JLS 14.14.2中所读到的,增强的for循环大致转换为传统的for循环:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
    TargetType Identifier = (TargetType) #i.next();
    Statement
}
     

#i是一个自动生成的标识符,它与发生增强for语句时的范围(第6.3节)中的任何其他标识符(自动生成的或其他标识符)不同。

从这里可以清楚地看出Expression只被评估过一次。

答案 1 :(得分:2)

正如您在下面的代码示例中所看到的,在增强型for上,要进行迭代的集合的初始化仅执行一次。因此,第二种选择更紧凑,不会影响性能。

package test;

public class Main {

        static class Basket {
            int[] items = { 1, 2, 3 };

        public int[] getItems() {
                System.out.println("in getItems()");
            return items;
        }

    }

    public static void main(String[] args) {
        Basket basket = new Basket();
        for (int item : basket.getItems()) {
            System.out.println(item);
        }

    }
}

答案 2 :(得分:0)

是的,第二个提高了代码的可读性。

如果您从网络获取对象然后在for循环中迭代它,那么我认为它会影响性能,因为您每次都在进行网络访问,这对于执行网络的小/单个对象也是低效的不建议访问。而不是从网络访问中获取一次将其存储在本地并迭代它

因此,第一个选项是在网络访问案例中进行性能优化 如果你的对象是本地的,那么任何方法都可以。不会有太大的性能差异。

答案 3 :(得分:0)

我不认为它每次都会调用getter。如果是这样,它每次都会得到新的列表,Loop不会中断。你可以通过在getter方法中放入简单的 Sysout 来测试它。这两种情况的表现相同。