【问题标题】:Does JVM create an iterator when it iterates over array with for-each loop?当使用 for-each 循环遍历数组时,JVM 会创建一个迭代器吗?
【发布时间】:2015-05-12 11:08:43
【问题描述】:

对不起,如果已经问过了,但我在 stackoveflow 上没有找到答案,也没有看到关于这个领域的官方教程。

问题就在标题中——如果我们有类似的代码

int[] array = new int[20];
for (int el : array) {
   ...
}

JVM 会作为标准循环运行它

for (int i = 0; i < array.length; i++)

或者它会创建一个迭代器?

UPD此链接可能有助于完成答案

Fastest way to iterate an Array in Java: loop variable vs enhanced for statement

【问题讨论】:

  • 你想知道的原因是什么? JVM和优化器可以为所欲为。
  • @chokdee 这是关于优化的。我有一个方法可以在预定义的字符串列表上运行,并检查该列表是否包含包含特定字符串的项目。此方法用作大型应用程序缓存(10k-100k 项)的谓词,因此我们发现 JVM 每次遍历都会创建数千个迭代器。现在它将被重新写入数组,我想知道迭代器实例化。
  • 你测量结果了吗?我写了一个简单的 10 万次迭代的测试,结果都一样
  • 在这里看到同样的问题:stackoverflow.com/questions/1006395/…
  • @chokdee 感谢您的链接,我知道我需要字节码来验证它,我只是不想浪费时间在可能已经有人检查过的事情上。

标签: java foreach iterator


【解决方案1】:

Java 中的数组不实现 Iterable 接口,因此您无法从数组中获取迭代器。此外,您不能在 int 等原始类型上使用 Iterator,因为原始类型不能是泛型参数。例如。如果你想要一个迭代器,你必须改用一个迭代器,如果它由 int[] 支持,这将导致大量的自动装箱和 -unboxing。

JVM 不太可能为数组上的 for-each 循环创建迭代器,因为它的效率非常低。

事实上,编译器会将 for-each 循环转换为索引 for 循环。您可以通过查看该方法的反编译字节码来检查它:

源代码:

public void test() {
    int[] array = new int[20];
    for (int el : array) {
        System.out.println("test");
    }
}

反编译的字节码:

public void test() {
    int[] array = new int[20];
    int[] var2 = array;
    int var3 = array.length;

    for(int var4 = 0; var4 < var3; ++var4) {
        int var10000 = var2[var4];
        System.out.println("lol");
    }

}

【讨论】:

    【解决方案2】:

    for-each 循环是普通 for 循环的可迭代形式,是一种更好构建的数据结构。

    cars 是一个数组,那么例如:-

      for(Car car: cars){
           //car.name() = audi...
           ....
            }
    

    其实和下图是一样的代码……

    for(Iterator<Car> iterator = cars.iterator(); iterator.hasNext(); ){
       Car car = iterator.next();
       //car.name() = audi...
       ......
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-21
      • 2015-04-04
      • 2013-10-15
      • 1970-01-01
      相关资源
      最近更新 更多