Java

java 闭包( lambda表达式)

2021-09-12  本文已影响0人  zhbi98

1. lambda表达式简介

闭包也被称为 lambda 表达式,让您能够使用运箭头算符“->”来创建只有一个方法的类的对象,它是推动 Java 8 发布的最重要新特性,使用 Lambda 表达式可以使代码变的更加简洁紧凑,典型的应用是JavaFX的事件响应函数

lambda表达式格式:
(形式参数) -> {代码块}

例如最简单的lambda表达式:

Runnable runner = () -> { System.out.println("Hello,World!"); };
即:
Runnable runner = () -> { 
    System.out.println("Hello,World!");
 };

2. lambda表达式的简化

其实lambda表达式和匿名内部类是相似的,可以认为lambda表达式就是由匿名内部类简化而来。

Interface01这是一个接口,现在使用匿名内部类来实现接口中的方法如下:

Interface01这是一个接口

Interface01 interface01 = new Interface01() {
    @Override
    public void show() {
        System.out.println("啦啦啦");
    }
};
interface01.show();

在匿名内部类的写法中,我们知道new的一定是个接口,所以需要省略接口名和大括号,所以得到如下:

image.png

因为接口内部只有一个抽象方法,所以需要省略抽象方法的名称、修饰符、返回值,所以得到如下:

image.png

结合Lambda的格式(形式参数) -> {代码块},在参数的小括号和代码块的大括号中间加 -> 符号,所以得到如下:

Interface interface01 = ()->{System.out.println("啦啦啦")}

3. 带参数的lambda表达式

设存在一个接口Interface02如下:

public interface Interface02 {
    int add(int a, int b);
}

lambda表达式实现接口:

Interface02 interface02 = (int a,int b) -> {
    return a+b;
};
interface02.add(1,2);

参数类型可以省略,但不能只省略一部分【如改为(int a,b)】

Interface02 interface02 = (a, b) -> {
    return a+b;
};
interface02.add(1,2);

如果代码块语句只有一行,可以省略大括号和分号。如果这一行包括return,return也必须要省略

Interface02 interface02 = (a, b) -> a+b;
interface02.add(1,2);

如果参数只有一个,可以省略参数的小括号

Interface03 in03 = (a) -> System.out.println(a);
即:
Interface03 in03 = a -> System.out.println(a);

4. lambda表达式实现接口

interface Proudcts {
    public void proudcts();
}


class GoogleProudct {
    GoogleProudct(Proudcts pd) {
        pd.proudcts();
    }
}


interface Addition2 {
    public void addition2(int a, int b);
}


class Sum {
    Sum(Addition2 addt) {
        addt.addition2(10, 20);
    }
}


interface Addition {
    public int addition(int a, int b);
}


public class LambdaLearn {
    public static void main(String[] args) {
        /**
         * Use lambda to implement an interface 
         * with only one abstract method
         */
        GoogleProudct gp = new GoogleProudct(() -> {
            System.out.println("Android OS 10");
        });

        /**
         * (argument) -> (body)
         * (arg1, arg2...) -> { body }
         */
        Sum sum = new Sum((i, j) -> {
            System.out.println(i + j);
        });

        /**
         * (argument) -> (body)
         * (arg1, arg2...) -> { body }
         */
        Addition additions = (i, j) -> {
            return i + j;
        }; // Addition additions = (i, j) -> i + j;
        System.out.println("Addition:" + additions.addition(100, 200));

        additions = (i, j) -> (i + j); // Addition addition = (i, j) -> {return(i + j)};
        System.out.println("Addition:" + additions.addition(300, 500));
    }
}

5. 注意事项

使用Lambda必须要有上下文环境,如果没有相应的前因后果,编译器也不知道我们表达是具体是哪个接口。编译器可以通过根据局部变量的赋值得知
Runnable r = ()-> xxxx;
根据调用方法的参数得知
new Thread(()-> xxxx).start();

上一篇下一篇

猜你喜欢

热点阅读