• 对于Java中的Loop或For-each,哪个更快


    Which is Faster For Loop or For-each in Java

    对于Java中的Loop或Foreach,哪个更快

    通过本文,您可以了解一些集合遍历技巧。

    Java遍历集合有两种方法。一个是最基本的for循环,另一个是jdk5引入的for each。通过这种方法,我们可以更方便地遍历数组和集合。但是你有没有想过这两种方法?哪一个遍历集合更有效?

    for-each实现方法

    For-each不是一种新语法,而是Java的语法糖( 语法糖百度百科 )。在编译时,编译器将此代码转换为迭代器实现,并将其编译为字节码。我们可以通过执行命令 javap-verbose-Testforeach反编译以下编译代码:

    public class TestForeach {
        List integers;
        public void testForeach(){
            for(Integer i : integers){
    
            }
        }
    }

    获得的详细字节码如下:

    public void testForeach();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=3, args_size=1
             0: aload_0
             1: getfield      #2                  // Field integers:Ljava/util/List;
             4: invokeinterface #3,  1            // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
             9: astore_1
            10: aload_1
            11: invokeinterface #4,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
            16: ifeq          32
            19: aload_1
            20: invokeinterface #5,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
            25: checkcast     #6                  // class java/lang/Integer
            28: astore_2
            29: goto          10
            32: return
          LineNumberTable:
            line 11: 0
            line 13: 29
            line 14: 32
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
               29       0     2     i   Ljava/lang/Integer;
                0      33     0  this   Ltest/TestForeach;
    }

    此字节码的一般含义是使用 getfileld 命令来获取 integers 变量并且调用 List.iterator 来获取迭代器实例和调用 iterator.hasNext 。如果返回 true ,调用 iterator.next 方法。

    请看,这是迭代器遍历集合的实现逻辑。

    基准测试

    现在让我们使用for循环方法和for-each方法进行测试。

    public class ForLoopTest {
    
        public static void main(String[] args) {
            List arrayList = new ArrayList<>();
            for (int i = 0; i < 10000000; i++) {
                arrayList.add(i);
            }
    
            long arrayListStartTime = System.currentTimeMillis();
            for (int i = 0; i < arrayList.size(); i++) {
                arrayList.get(i);
            }
    
            long arrayListCost =System.currentTimeMillis()-arrayListStartTime;
            System.out.println("ArrayList for loop traversal cost: "+ arrayListCost);
    
            long arrayListForeachStartTime = System.currentTimeMillis();
            for (Integer integer : arrayList) {
    
            }
    
            long arrayListForeachCost =System.currentTimeMillis()-arrayListForeachStartTime;
            System.out.println("ArrayList foreach traversal cost: "+ arrayListForeachCost);

    这是测试结果:

    如你所见,结果是显而易见的。对于ArrayList,使用For循环方法的性能优于For each方法。

    我们可以说for循环比for-each好吗?

    答案是否定的。在下一个基准测试中,我们将ArrayList更改为LinkedList。

    同样,这里是测试结果。

    原因分析

    一些初学者可能想知道为什么ArrayList使用for循环方法遍历得更快,而LinkedList则更慢,速度也非常慢?

    这由ArrayList和LinkedList数据结构决定。

    ArrayList底层使用数组存储元素。数组是连续的内存空间。数据可以通过索引获得。时间复杂度为O(1),因此速度很快。

    LinkedList的底层是一个双向链表。使用for循环实现遍历,每次都需要从链表的头节点开始。时间复杂度为O(n*n)。

    结论

    1. 使用ArrayList时,for循环方法更快,因为for-each由迭代器实现,并且需要执行并发修改验证。
    2. 使用LinkedList时,for-each比for循环快得多,因为LinkedList是通过使用双向链表实现的。每个寻址都需要从头节点开始。如果我们需要遍历LinkedList,我们需要避免使用for循环。
    3. 使用迭代器模式,for-each不需要关心集合的具体实现。如果需要替换集合,无需修改代码即可轻松替换。
  • 相关阅读:
    仿bilibili视频弹幕播放器介绍&搭建
    springboot+vue+elementui家具销售电商管理平台java
    linux常用命令及解释大全(二)
    Dynamic Wallpaper v17.4 mac版 动态视频壁纸 兼容 M1/M2
    Python - Wave2lip 环境配置与 Wave2lip x GFP-GAN 实战 [超详细!]
    基于go-zero的rpc服务示例
    【学习总结】NoSQL重点归纳
    基于JAVA企业公司网站系统设计与实现 开题报告
    Java9-17新特性一览,了解少于3个你可能脱节了
    MybatisPlus的基础使用
  • 原文地址:https://blog.csdn.net/Candyz7/article/details/126378647