lambda表达式

Lambda是java8添加的一个新的特性,也可称为闭包,它允许把函数作为一个方法的参数,使用Lambda表达式可以使代码变的更加简洁紧凑

语法

Java8中引入了一个新的操作符 -> 该操作符称为箭头操作符或Lambda操作符

Lambda的格式为 (参数列表) -> {方法体}(参数列表) -> 表达式

以下是Lambda表达式的重要特征

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

使用要求

  • 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法
  • Lambda设计初衷是简洁,所以尽量避免在Lambda的方法体中使用多行的代码块

代码演示

下面是几种情况下的用法

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)

下面是具体用法

无参,一条语句,无返回值

package top.coor.lambdademo.test1;

/**
 * @program: lambda-demo
 * @description:
 * @author: coortop
 * @create: 2020-07-03 16:33
 **/
public class Test1 {
    public static void main(String[] args) {
        Runnable runnable = () -> System.out.println(Thread.currentThread().getName() + "线程启动了");
        new Thread(runnable, "a").start();
        new Thread(runnable, "b").start();
        new Thread(runnable, "c").start();
    }
}

无参,多条语句,无返回值

package top.coor.lambdademo.test2;

/**
 * @program: lambda-demo
 * @description:
 * @author: coortop
 * @create: 2020-07-03 16:36
 **/
public class Test2 {
    public static void main(String[] args) {
        //Lambda设计初衷是简洁,所以尽量避免这样使用
        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName() + "线程启动了");
            System.out.println("....");
        };
        new Thread(runnable, "a").start();
        new Thread(runnable, "b").start();
        new Thread(runnable, "c").start();
    }
}

一个参数,无返回值

package top.coor.lambdademo.test3;

/**
 * @program: lambda-demo
 * @description:
 * @author: coortop
 * @create: 2020-07-03 16:39
 **/
public class Test3 {
    public static void main(String[] args) {
        Demo demo = (num) -> System.out.println("传递的参数是" + num);
        demo.fun(6);
    }

    @FunctionalInterface
    interface Demo {
        void fun(int i);
    }
}

两个参数,有返回值

package top.coor.lambdademo.test4;

/**
 * @program: lambda-demo
 * @description:
 * @author: coortop
 * @create: 2020-07-03 16:46
 **/
public class Test4 {
    public static void main(String[] args) {
        Demo demo = (a, b) -> a + b;
        int sum = demo.sum(23, 64);
        System.out.println(sum);
    }

    @FunctionalInterface
    interface Demo {
        int sum(int a, int b);
    }
}

函数式接口

有且仅有一个抽象方法的接口,称为函数式接口。

为了避免后来的人在接口中增加新的接口函数,导致其有多个接口函数需要被实现,变成非函数式接口,引入了一个新的注解 @FunctionalInterface ,可以把他它放在一个接口前,表示这个接口是一个函数式接口,加上它的接口不会被编译,如果加上此标记就不能再添加其他的抽象方法,否则会报错。

变量作用域

Lambda表达式只能引用标记了final的外层局部变量,这就是说不能在Lambda内部修改定义在域外的局部变量,否则会编译错误。

package top.coor.lambdademo.test5;

/**
 * @program: lambda-demo
 * @description:
 * @author: coortop
 * @create: 2020-07-03 17:15
 **/
public class Test5 {
    private final static int num = 5;

    public static void main(String[] args) {
        Demo demo = (i) -> System.out.println(i + num);
        demo.convert(3);
    }

    @FunctionalInterface
    interface Demo {
        void convert(int i);
    }
}

Lambda表达式更多的是用于直接使用内置函数式接口和自定义的一些简单功能的情况下使用~