Java8知识点总结之Lambda表达式

225 阅读3分钟

一、Lambda介绍

Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以 传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更

灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升

二、Lambda表达式可以分为两部分

lambda操作符或者叫箭头操作符:->

左侧: 指定了 Lambda 表达式需要的参数列表

右侧: 指定了 Lambda 体,是抽象方法的实现逻辑,也即Lambda 表达式要执行的功能

三、Lambda六种语法格式

1.语法格式一:无参,无返回值

 Runnable r1 = () -> System.out.println("Hello Lambda");

2.语法格式二:Lambda 需要一个参数,但是没有返回值。

Consumer<String> con = (String x) -> System.out.println(x);

3.语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”

Consumer<String> con = (x) -> System.out.println(x);

4.语法格式四:Lambda 若只需要一个参数时,参数的小括号可以省略

Consumer<String> con = x -> System.out.println(x);

5.语法格式五:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值

Comparator<Integer> com=(x,y)->{
    System.out.println(x+y);
    return Integer.compare(x,y);
}

6.语法格式六:当 Lambda 体只有一条语句时,return 与大括号若有,都可以省略

Comparator<Integer> com = (x,y) -> Integer.compare(x,y);

四、方法引用与构造器引用

1.方法引用

1.1方法引用介绍

  • 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
  • 方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就 是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向 一个方法,可以认为是Lambda表达式的一个语法糖。
  • 要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的 方法的参数列表和返回值类型保持一致!
  • 格式:使用操作符 “ :: ” 将类(或对象) 与 方法名分隔开来。
  • 如下三种主要使用情况:

对象::实例方法名

类::静态方法名

类::实例方法名

1.1方法引用列子

// 例子
Consumer<String> con = x -> System.out.println(x);
// 等同于
Consumer<String> con = System.out::println;

// 例子
Comparator<Integer> com=(x,y)->Integer.compare(x,y);
// 等同于
Comparator<Integer> com=Integer::compare;
int value=com.compare(6,5)

注意:当函数式接口方法的第一个参数是需要引用方法的调用者,并且第二 个参数是需要引用方法的参数(或无参数)时:ClassName::methodName

2.构造器引用

2.1构造器引用介绍

格式: ClassName::new

与函数式接口相结合,自动与函数式接口中方法兼容。 可以把构造器引用赋值给定义的方法,要求构造器参数列表要与接口中抽象 方法的参数列表一致!且方法的返回值即为构造器对应类的对象。

2.2构造器引用例子

// 例子
Function<Integer, MyClass> function =(n)->new MyClass(n);
// 等同于
Function<Integer, MyClass> function = MyClass::new;

3.数组引用

格式: type[] :: new

// 列子
Function<Integer, Integer[]> function =(n)->new Integer[n];
// 等同于
Function<Integer, Integer[]> function =Integer[n]::new;

五、变量作用域

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

六、扩展

上述 Lambda 表达式中的参数类型都是由编译器推断得出的。Lambda 表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序 的上下文,在后台推断出了参数的类型。Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的。这就是所谓的“类型推断