• 【java8】Stream底层原理解析


    Stream底层原理解析

    1.示例代码

    public class Java8_01_Source_Main {
    
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            list.add("Red");
            list.add("Green");
            list.add("Blue");
            long lengthyColors = list.stream().filter(c -> c.length() > 3).count();
            System.out.println(lengthyColors);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    javap -c -p Java8_01_Source_Main  查看class文件
    
    • 1
    > javap -c -p  Java8_01_Source_Main
    警告: 二进制文件Java8_01_Source_Main包含com.xiaofei.antjava8.源码.Java8_01_Source_Main
    Compiled from "Java8_01_Source_Main.java"
    public class com.xiaofei.antjava8.源码.Java8_01_Source_Main {
      public com.xiaofei.antjava8.源码.Java8_01_Source_Main();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."":()V
           4: return
    
      public static void main(java.lang.String[]);
        Code:
           0: new           #2                  // class java/util/ArrayList
           3: dup
           4: invokespecial #3                  // Method java/util/ArrayList."":()V
           7: astore_1
           8: aload_1
           9: ldc           #4                  // String Red
          11: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
          16: pop
          17: aload_1
          18: ldc           #6                  // String Green
          20: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
          25: pop
          26: aload_1
          27: ldc           #7                  // String Blue
          29: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
          34: pop
          35: aload_1
          36: invokeinterface #8,  1            // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
          41: invokedynamic #9,  0              // InvokeDynamic #0:test:()Ljava/util/function/Predicate;
          46: invokeinterface #10,  2           // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
          51: invokeinterface #11,  1           // InterfaceMethod java/util/stream/Stream.count:()J
          56: lstore_2
          57: getstatic     #12                 // Field java/lang/System.out:Ljava/io/PrintStream;
          60: lload_2
          61: invokevirtual #13                 // Method java/io/PrintStream.println:(J)V
          64: return
    
      private static boolean lambda$main$0(java.lang.String);  // c -> c.length() > 3
        Code:
           0: aload_0
           1: invokevirtual #14                 // Method java/lang/String.length:()I
           4: iconst_3
           5: if_icmple     12
           8: iconst_1
           9: goto          13
          12: iconst_0
          13: ireturn
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    2.分析结论

    通过字节码可以看到 invokedynamic 指令以某种方式负责创建 Predicate 实例。

    此方法以 字符串 作为输入,然后执行以下步骤:

    • 计算输入长度(invokevirtual on length)
    • 将长度与常量 3 进行比较(if_icmple 和 iconst_3)
    • 如果长度小于或等于 3,则返回 false

    Java 7中之前,JVM只是有四个方法调用类型:

    • invokevirtual 调用正常类方法,
    • invokestatic 调用静态方法,
    • invokeinterface 调用接口的方法,
    • invokespecial 调用构造函数或私有方法。

    对于lambda表达式,Java 不是在编译时创建匿名内部类,而是在运行时通过调用动态创建它们

  • 相关阅读:
    【云原生 | 20】Docker运行Web服务实战之Apache
    求最大公约数和最小公倍数
    解决WordPress升级后提示:无需升级,您的WordPress数据库已经是最新的了
    SpringBoot集成Dubbo、Redis、MyBatis、Spring、SpringMVC、JSP
    聊聊 C# 方法重载的底层玩法
    数据结构(四)--队列及面试常考的算法
    MySQL---DML语句对数据进行增删改操作
    oracle数据库核心知识
    【数据结构-队列 二】【单调队列】滑动窗口最大值
    【每日一题】43. 字符串相乘
  • 原文地址:https://blog.csdn.net/qyj19920704/article/details/126005615