Java 中for循环和foreach循环哪个更快?

前言

在Java编程中,循环结构是程序员常用的控制流程,而for循环和foreach循环是其中比较常见的两种形式。关于它们哪一个更快的讨论一直存在。本文旨在探究Java中的for循环和foreach循环的性能差异,并帮助读者更好地选择适合自身需求的循环方式。通过详细比较它们的遍历效率、数据结构适用性和编译器优化等因素,我们将为大家揭示它们的差异和适用场景,以便您能够做出更明智的编程决策。

for循环与foreach循环的比较

小编认为for和foreach 之间唯一的实际区别是,对于可索引对象,我们无权访问索引。

Java 复制代码
for(int i = 0; i < mylist.length; i++) {
 if(i < 5) {
 //do something
 } else {
 //do other stuff
 }
}

但是,我们可以使用 foreach 创建一个单独的索引 int 变量。例如:

Java 复制代码
int index = -1;
for(int myint : mylist) {
 index++;
 if(index < 5) {
 //do something
 } else {
 //do other stuff
 }
}

现在写一个简单的类,其中有 foreachTest() 方法,该方法使用 forEach 迭代列表。

Java 复制代码
import java.util.List;

public class ForEachTest {
        List<Integer> intList;
        
    public void foreachTest(){
        for(Integer i : intList){

        }
    }
}

编译这个类时,编译器会在内部将这段代码转换为迭代器实现。小编通过执行 javap -verbose IterateListTest 反编译代码。

Java 复制代码
public void foreachTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=3, args_size=1
         0: aload_0
         1: getfield      #19                 // Field intList:Ljava/util/List;
         4: invokeinterface #21,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
         9: astore_2
        10: goto          23
        13: aload_2
        14: invokeinterface #27,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
        19: checkcast     #33                 // class java/lang/Integer
        22: astore_1
        23: aload_2
        24: invokeinterface #35,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
        29: ifne          13
        32: return
      LineNumberTable:
        line 9: 0
        line 12: 32
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      33     0  this   Lcom/greekykhs/springboot/ForEachTest;
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 13
          locals = [ class com/greekykhs/springboot/ForEachTest, top, class java/util/Iterator ]
          stack = []
        frame_type = 9 /* same */

从上面的字节码我们可以看到:

a). getfield命令用于获取变量整数。

b).调用List.iterator获取迭代器实例

c).调用iterator.hasNext,如果返回true,则调用iterator.next方法。

下边来做一下性能测试。在 IterateListTest 的主要方法中,创建了一个列表并使用 for 和 forEach 循环对其进行迭代。

Java 复制代码
import java.util.ArrayList;
import java.util.List;

public class IterateListTest {
        public static void main(String[] args) {
                List<Integer> mylist = new ArrayList<>();
        for (int i = 0; i < 1000000; i++) {
            mylist.add(i);
        }

        long forLoopStartTime = System.currentTimeMillis();
        for (int i = 0; i < mylist.size(); i++) {mylist.get(i);}

        long forLoopTraversalCost =System.currentTimeMillis()-forLoopStartTime;
        System.out.println("for loop traversal cost for ArrayList= "+ forLoopTraversalCost);

        long forEachStartTime = System.currentTimeMillis();
        for (Integer integer : mylist) {}

        long forEachTraversalCost =System.currentTimeMillis()-forEachStartTime;
        System.out.println("foreach traversal cost for ArrayList= "+ forEachTraversalCost);
        }
}

结果如下:

总结

观察结果显示,for循环的性能优于for-each循环。然后再使用LinkedList比较它们的性能差异。对于 LinkedList 来说,for-each循环展现出更好的性能。ArrayList内部使用连续存储的数组,因此数据的检索时间复杂度为 O(1),通过索引可以直接访问数据。而 LinkedList 使用双向链表结构,当我们使用 for 循环进行遍历时,每次都需要从链表头节点开始,导致时间复杂度达到了 O(n*n),因此在这种情况下,for-each 循环更适合操作 LinkedList。

相关推荐
JustHappy2 小时前
古法编程秘籍(二):什么是代码模块化?别背概念,把房间收拾明白就够了
前端·后端
小江的记录本2 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
IT_陈寒5 小时前
Python闭包里藏的这个坑,差点让我加班到凌晨
前端·人工智能·后端
IT_陈寒5 小时前
Java注解空指针?这个坑我踩得莫名其妙
前端·人工智能·后端
土狗TuGou6 小时前
SQL内功笔记 · 第8篇:事务的四大特性与隔离级别
数据库·笔记·后端·sql·mysql·oracle
ZengLiangYi6 小时前
React Query + REST API 最佳实践
javascript·后端·react.js
星浩AI6 小时前
项目实战:合同智能审批 · LangGraph + HITL 人机协同方案 [有源码]
后端·langchain·agent
JavaGuide6 小时前
Codex 接入第三方模型 DeepSeek、GLM、Kimi 教程:CC-Switch 和 Codex++ 两种方案对比
后端·ai编程
ZengLiangYi6 小时前
Fastify 加 Electron:把 Web 服务嵌进桌面应用
前端·javascript·后端
李白你好7 小时前
页面资产梳理 · 技术指纹识别 · Spring 端点探测
java·后端·spring