美文网首页
Java lambda 你了解多少

Java lambda 你了解多少

作者: 嗨技术 | 来源:发表于2018-05-05 15:37 被阅读0次

    最近在编写一些Java业务,使用了 Lambda语法,所以有必要整理一下lambda相关的知识,以便能够加深理解。

    • 什么是lambda表达式?
    • lambda语法格式
    • lambda 表达式重要特征
    • 函数式接口
    • lambda使用
    • 匿名类和lambda中this指针
    • 参考网站

    1、什么是lambda表达式?

    Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
    Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
    使用 Lambda 表达式可以使代码变的更加简洁紧凑。

    2、lambda语法格式

    (parameters) -> expression
    
    (parameters) -> {expression;}
    

    3、lambda 表达式重要特征

    • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
    • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
    • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
    • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

    4、函数式接口

    • 什么是函数式接口:

      • 函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。 这类接口只定义了唯一的抽象方法的接口(除了隐含的Object对象的公共方法), 因此最开始也就做SAM类型的接口(Single Abstract Method)。
      • 函数式接口中可以额外定义Object中多个抽象方法,但这些抽象方法签名必须和Object的 public 方法一样
    • Java8新增函数式接口

      • Predicate -- 传入一个参数,返回一个bool结果, 方法为boolean test(T t)
      • Consumer -- 传入一个参数,无返回值,纯消费。 方法为void accept(T t)
      • Function -- 传入一个参数,返回一个结果,方法为R apply(T t)
      • Supplier -- 无参数传入,返回一个结果,方法为T get()
      • UnaryOperator -- 一元操作符,继承Function,传入参数的类型和返回类型相同。
      • BinaryOperator -- 二元操作符, 传入的两个参数的类型和返回类型相同, 继承BiFunction

    5、lambda使用

    • 循环打印List<Integer>中的值
    • 老方法:for(Integer i: list) { System.out.println(i);}
    • Lambda表达式:list.forEach(x->System.out.println(x));
    public static void main(String... args) {
        List<Integer> list = Arrays.asList(10, 5, 4, 1, 76);
    
        for(Integer i: list) {
            System.out.println(i);
        }
    
        list.forEach(x -> System.out.println(x));
    }
    

    -反编译代码

    
    for:
    45: aload_1
    46: invokeinterface #5,  1            // InterfaceMethod java/util/List.iterator:()Ljava/util/I
    terator;
    51: astore_2
    52: aload_2
    53: invokeinterface #6,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
    58: ifeq          81
    61: aload_2
    62: invokeinterface #7,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/O
    bject;
    67: checkcast     #2                  // class java/lang/Integer
    70: astore_3
    71: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
    74: aload_3
    75: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/Object;
    )V
    78: goto          52
    
    
    
    lambda:
    81: aload_1
    82: invokedynamic #10,  0             // InvokeDynamic #0:accept:()Ljava/util/function/Consumer
    ;
    87: invokeinterface #11,  2           // InterfaceMethod java/util/List.forEach:(Ljava/util/fun
    ction/Consumer;)V
    
    
    private static void lambda$main$0(java.lang.Integer);
        Code:
           0: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
           3: aload_0
           4: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/Object;
    )V
           7: return
    
    
    • lambda 编译的时候生成了一个动态方法,调用也是执行命令invokedynamic

    6、匿名类和lambda中this指针

    • 示例代码
    public void test1(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(this.toString());
            }
        }).start();
    
        new Thread(()->System.out.println(this.toString())).start();
    }
    
    
    • 反编译
    public class com.yuxiu.test.Main {
    
        public void test1();
            Code:
               0: new           #5                  // class java/lang/Thread
               3: dup
               4: new           #6                  // class com/yuxiu/test/Main$1
               7: dup
               8: aload_0
               9: invokespecial #7                  // Method com/yuxiu/test/Main$1."<init>":(Lcom/yuxiu/test
        /Main;)V
              12: invokespecial #8                  // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;
        )V
              15: invokevirtual #9                  // Method java/lang/Thread.start:()V
              18: new           #5                  // class java/lang/Thread
              21: dup
              22: aload_0
              23: invokedynamic #10,  0             // InvokeDynamic #0:run:(Lcom/yuxiu/test/Main;)Ljava/lang
        /Runnable;
              28: invokespecial #8                  // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;
        )V
              31: invokevirtual #9                  // Method java/lang/Thread.start:()V
              34: return
        
        
        private void lambda$test1$0();
            Code:
               0: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
               3: aload_0
               4: invokevirtual #12                 // Method java/lang/Object.toString:()Ljava/lang/String;
               7: invokevirtual #13                 // Method java/io/PrintStream.println:(Ljava/lang/String;
            )V
              10: return
    }
    
    
    • 结论:
      • 匿名类this指向匿名类

      • lambda中this指向lambda外的类

    7、参考网站

    相关文章

      网友评论

          本文标题:Java lambda 你了解多少

          本文链接:https://www.haomeiwen.com/subject/ovferftx.html