Lambda表达式

一、概述

1.什么是函数式接口?

想要知道Lambda表达式,首先先要了解函数式接口。
函数式接口是指根据Java语言规范的定义,一个使用了@FunctionalInterface注解的接口类型声明将被视为一个函数式接口。
翻译FunctionalInterface注解类:从概念上讲,一个函数式接口有且只有一个抽象方法。由于默认方法(静态方法同理)已经有了实现,所以它们不是抽象方法。并且如果一个接口中声明的抽象方法是重写了超类Object类中任意一个public方法(例如:equals()方法),那么这些抽象方法并不会算入接口的抽象方法数量中。因为任何接口的实现都会从其父类Object或其它地方获得这些方法的实现。例如:Comparator接口
image

2.什么是Lambda表达式

Lambda表达式是 Java8 引入的一种匿名函数语法,它提供了一种更简洁的方式来表示函数式接口的实例。举例说明:
TreeSet是一个有序集合,我们在使用TreeSet存储时应该指定它的排序方法(即比较大小的方法),因此我们可以传入一个Comparator的实现类,在实现类中重写Comparator的compare()方法,当然也可以通过使用匿名内部类的方式来简化该步骤,如下:
image
执行结果如下:
image
以上写法在java8时,可以通过Lambda表达式来简化:
image
执行结果仍然没有改变:
image
当然,上面的Lambda表达式还可以再简化:
image
最后,上面的Lambda表达式还可以使用方法引用来简化,这个后面再说。由上可见,Lambda表达式(匿名函数)是一种无需声明函数名的简洁代码块,可直接传递函数逻辑作为参数。其核心价值为:
1)简化代码:替代冗余的匿名内部类。
2)函数式编程:支持将函数作为参数传递。
3)并行处理:为Stream API提供高效操作基础。
注意:匿名内部类不等于Lambda表达式,因为在编译后,匿名内部类会生成.class文件,而Lambda表达式不会。

二、Lambda表达式的使用

1.语法

Lambda表达式的使用语法就只有一个:(parameters) -> { expression or statements },例如:
1)无参无返回值:() -> { 方法体 };
2)单参无返回值:(参数类型 形参名) -> { 方法体 };
3)多惨无返回值:(参数类型1 形参名1, 参数类型2 形参名2,参数类型3 形参名3) -> { 方法体 };
4)无参有返回值:() -> { return 返回值 };
5)单参有返回值:(参数类型 形参名) -> { return 返回值 };
6)多参有返回值:(参数类型1 形参名1, 参数类型2 形参名2,参数类型3 形参名3) -> { return 返回值 };

2.精简规则

1)形参类型可省,但要省全省(不能只省其中部分)。例如:
(参数类型1 形参名1, 参数类型2 形参名2,参数类型3 形参名3) -> { 方法体 };
(形参名1, 形参名2, 形参名3) -> { 方法体 };

2)若形参只有一个,则类型和小括号都可以省。例如:
(参数类型 形参名) -> { 方法体 };
形参名 -> { 方法体 };

3)若方法体只有一行语句,则大括号可以省。例如:
o -> { System.out.println(o) };
o -> System.out.println(o) ;

4)若方法体只有一行return语句,则大括号可以省,同时return必须省。例如:
o -> { return o + 1 };
o -> o + 1 ;

注:Lambda表达式可能会被其他人认为在简化代码量的同时降低了代码的可读性,因此在学习中,我们应该保证能读懂其他人写的Lambda表达式(源码中有使用),再根据个人喜好方式来编写代码。

三、JDK8新增的4个基本的函数式接口

1. java.util.function.Consumer 接口

该接口被译为消费者,接口中只有一个单参无返回值的方法,可以使用泛型。
image

2. java.util.function.Supplier 接口

该接口被译为生产者,接口中只有一个无参有返回值的抽象方法,可以使用泛型,方法返回值就是形参类型。
image

3. java.util.function.Function 接口

该接口被译为转换者,接口中只有一个单参无返回值的抽象方法,可以使用泛型,方法返回值是非形参类型。
image

4. java.util.function.Predicate 接口

该接口被译为判断者,接口中只有一个单参有返回值的抽象方法,可以使用泛型,方法返回值是一个布尔类型。
image

四、方法引用

1.概述

方法引用(Method References)是 Java 8 中与 Lambda 表达式配合使用的语法糖,用于进一步简化 Lambda 代码,直接指向已有的方法。它通过 :: 双冒号操作符实现,是函数式编程的进阶技巧。
核心目标:用方法名替代冗余的Lambda参数传递逻辑。

2.使用条件与四种类型及其语法模板

当Lambda代码符合箭头右侧仅包含一个方法调用的模式时,即Lambda的方法体有且仅有一句语句,且该语句是调用一个方法时,可以使用方法引用。
一共有四种类型:

类型 语法格式 等价的Lambda表达式 典型场景
静态方法引用 类名::静态方法 (args) -> 类名.静态方法(args) Math::max
实例方法引用 对象::实例方法 (arg) -> 对象.实例方法(arg) System.out::println
类引用实例方法 类名::实例方法 (obj, arg) -> obj.实例方法(arg) String::toUpperCase
构造器引用 类名::new (args) -> new 类名(args) ArrayList::new

1)静态方法引用
要求:函数式接口中方法的返回值类型和形参列表与方法体内部通过某个类名调用的某个静态方法的返回值类型和形参列表一致。
2)实例方法引用
要求:函数式接口中方法的返回值类型和形参列表与方法体内部通过某个对象调用的某个实例方法的返回值类型和形参列表一致。
3)类引用实例方法(特殊方法引用)
要求:函数式接口中,抽象方法第一个形参作为方法调用的对象,从第二个形参开始(或者无参)可以对应到被调用的实例方法的参数列表中,并且抽象方法与实例方法的返回值一致
4)构造方法引用
要求:函数式接口中方法的形参列表与创建对象所调用的构造方法形参列表一致,且返回值类型与创建对象一致

五、总结

Lambda表达式和方法引用都是为了简化代码量,但同时也是可读性降低,学习方法是多看,在流式开发中会使用的更多。

posted @ 2025-07-12 01:50  小心二次元T4z  阅读(17)  评论(0)    收藏  举报