# 1 本质

• `lambda`表达式本质上是对匿名内部类实例的一种简化写法。

### 1.1 案例

``````List<Integer> list = Arrays.asList(1, 3, 5, 7, 9, 2, 4, 6, 8, 10);
``````

``````default void sort(Comparator<? super E> c) {
// 省略方法体
}
``````

### 1、 创建`Comparator`的实现类

``````public class AscComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
}
``````

``````Comparator<Integer> ascComparator = new AscComparator();
list.sort(ascComparator);
``````

### 2、创建`Comparator`的匿名对象

``````Comparator<Integer> anonymousComparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
};
list.sort(anonymousComparator);
``````

``````list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
``````

### 3、`lambda`表达式

``````list.sort((o1, o2) -> o1.compareTo(o2));
``````

### 4、方法引用

``````list.sort(Integer::compare);
``````

## 1.2 本质

• `lambda`表达式本质上是Java对象。

``````public class LambdaExpression {
public void printConsumer(Consumer consumer) {
System.out.println(consumer.getClass());
System.out.println(consumer.getClass().getInterfaces()[0]);
System.out.println(consumer);
}
}
``````

### 1、案例1

``````LambdaExpression lambdaObjPrinter = new LambdaExpression();
lambdaObjPrinter.printConsumer(o -> o.getClass());
lambdaObjPrinter.printConsumer(o -> o.getClass());
``````

``````class lambda.LambdaExpression\$\$Lambda\$1/2003749087
interface java.util.function.Consumer
lambda.LambdaExpression\$\$Lambda\$1/2003749087@41629346
class lambda.LambdaExpression\$\$Lambda\$2/1078694789
interface java.util.function.Consumer
lambda.LambdaExpression\$\$Lambda\$2/1078694789@6d311334
``````
• 这证明了执行过程中会根据`lambda`表达式动态生成函数式接口的实现类，并创建该实现类的实例。
• 同时，先后执行的2个`lambda`表达式，尽管格式相同，仍然动态生成了2个实现类。

``````LambdaExpression lambdaObjPrinter = new LambdaExpression();
lambdaObjPrinter.printConsumer((o) -> {
o.getClass();
});
lambdaObjPrinter.printConsumer((o) -> {
o.getClass();
});
``````

### 2、案例2

``````LambdaExpression lambdaObjPrinter = new LambdaExpression();
for (int i = 0; i < 2; i++) {
lambdaObjPrinter.printConsumer(o -> o.getClass());
}
System.out.println("=============");
for (int i = 0; i < 2; i++) {
lambdaObjPrinter.printConsumer(o -> o.getClass());
}
``````

``````class lambda.LambdaExpression\$\$Lambda\$1/2003749087
interface java.util.function.Consumer
lambda.LambdaExpression\$\$Lambda\$1/2003749087@41629346
class lambda.LambdaExpression\$\$Lambda\$1/2003749087
interface java.util.function.Consumer
lambda.LambdaExpression\$\$Lambda\$1/2003749087@41629346
=============
class lambda.LambdaExpression\$\$Lambda\$2/1078694789
interface java.util.function.Consumer
lambda.LambdaExpression\$\$Lambda\$2/1078694789@6d311334
class lambda.LambdaExpression\$\$Lambda\$2/1078694789
interface java.util.function.Consumer
lambda.LambdaExpression\$\$Lambda\$2/1078694789@6d311334
``````
• 说明在不同`for`循环中（`while`等循环结果相同），只会动态生成1个实现类。

``````LambdaExpression lambdaObjPrinter = new LambdaExpression();

int i;
for(i = 0; i < 2; ++i) {
lambdaObjPrinter.printConsumer((o) -> {
o.getClass();
});
}

System.out.println("=============");

for(i = 0; i < 2; ++i) {
lambdaObjPrinter.printConsumer((o) -> {
o.getClass();
});
}
``````
• 说明这不是编译器编译的结果，应该是JVM执行时对循环语句中`lambda`表达式的优化。

# 2 基本语法

`lambda`表达式本质上是对函数式接口的匿名实现类实例的一种简化写法：方法格式和`lambda`表达式格式一一对应。

`lambda`表达式与之对应：
1、形参：`(t1, t2[, ……])`，对应方法的形参`(T1 t1, T2 t2[, ……])`
2、箭头：->，固定
3、方法体：{}，对应方法的方法体

## 2.1 分类

1. 没有形参：
``````() -> {
// 方法体
}
``````
1. 一个形参：
``````(t) -> {
// 方法体
}
``````
1. 多个形参：

(t1, t2[, ……]) -> {
// 方法体
}

2. 没有返回值：

``````() -> {
// 方法体
}
``````
1. 有返回值：
``````() -> {
// 方法体
return something;
}
``````

1、没有形参或多个形参（超过1个），需要带`()`

``````() -> {
// 方法体
}
(t1, t2[, ……]) {
// 方法体
}
``````

2、一个形参，可以省略`()`

``````(t) -> {
// 方法体
}
t -> {
// 方法体
}
``````

1、一行代码，可以省略`{}`（此时该行代码的`return``;`也必须省略）：

``````() -> {
System.out.println("Hello World!");
}
() -> System.out.println("Hello World!")
() -> {
return "Hello World!"
}
() -> "Hello World!"
``````

2、多行代码，不可以省略`{}`

``````() -> {
System.out.println("Hello");
System.out.println("World!");
}
() -> {
System.out.println("Hello");
return "Hello World!"
}
``````

## 2.2 案例

• 定义函数式接口，模拟不同类型的`lambda`表达式：
``````public class FunctionInterface {
interface AcceptEmpty {
void accept();
}

interface AcceptOne<T> {
void accept(T t);
}

interface AcceptMore<T, E> {
void accept(T t, E e);
}

interface ReturnVoid {
void returnVoid();
}

interface ReturnR<R> {
R returnR();
}
}
``````
• 定义调用类，接收不同的`lambda`表达式：
``````/**
* 调用函数式接口的服务类
* @param <T> 第一个形参类型
* @param <E> 第二个形参类型
* @param <R> 返回值类型
*/
public class Service<T, E, R> {
private T t;
private E e;

public Service(T t, E e) {
this.t = t;
this.e = e;
}

void acceptEmpty(FunctionInterface.AcceptEmpty acceptEmpty) {
acceptEmpty.accept();
}

void acceptOne(FunctionInterface.AcceptOne<T> acceptOne) {
acceptOne.accept(this.t);
}

void acceptMore(FunctionInterface.AcceptMore<T, E> acceptMore) {
acceptMore.accept(this.t, this.e);
}

void returnVoid(FunctionInterface.ReturnVoid returnVoid) {
returnVoid.returnVoid();
}

R returnR(FunctionInterface.ReturnR<R> returnR) {
return returnR.returnR();
}
}
``````
• 创建服务类实例：
``````Service<Integer, Integer, String> service = new Service<>(1, 2);
``````

### 1、没有形参

``````service.acceptEmpty(new FunctionInterface.AcceptEmpty() {
@Override
public void accept() {
System.out.println("没有形参");
}
});
service.acceptEmpty(() -> {
System.out.println("没有形参");
});
service.acceptEmpty(() -> System.out.println("没有形参"));
``````

### 2、一个形参

``````service.acceptOne(new FunctionInterface.AcceptOne<Integer>() {
@Override
public void accept(Integer t) {
System.out.println(t);
}
});
service.acceptOne((t) -> System.out.println(t));
service.acceptOne(t -> System.out.println(t));
``````

### 3、多个形参

``````service.acceptMore(new FunctionInterface.AcceptMore<Integer, Integer>() {
@Override
public void accept(Integer t, Integer e) {
System.out.println(t);
System.out.println(e);
}
});
service.acceptMore((t, e) -> {
System.out.println(t);
System.out.println(e);
});
``````

### 4、没有返回值

``````service.returnVoid(new FunctionInterface.ReturnVoid() {
@Override
public void returnVoid() {
System.out.println("没有返回值");
}
});
service.returnVoid(() -> System.out.println("没有返回值"));
``````

### 5、有返回值

``````service.returnR(new FunctionInterface.ReturnR<String>() {
@Override
public String returnR() {
return "3";
}
});
service.returnR(() -> "3");
``````

# 3 执行逻辑

• `lambda`表达式本质上是传递了一个动态生成的匿名对象，是一种假的函数式编程。

`lambda`表达式形式上看起来很像是函数式编程：将一个函数当作形参传给方法。

• 定义一个函数式接口：
``````public interface Lambda<T, R> {
R method(T t);
}
``````
• 定义调用类：
``````public class FakeFunctionalProgramming<T, R> {
private T t;
private Lambda<T, R> lambda;

public void setT(T t) {
this.t = t;
}

public void setLambda(Lambda<T, R> lambda) {
this.lambda = lambda;
}

public void doSomeThing() {
T t = before();
R r = lambda.method(t);
after(r);
}

public T before() {
return t;
}
public void after(R r) {
System.out.println(r);
}
}
``````
• 执行以下代码：
``````FakeFunctionalProgramming<String, String> ffp = new FakeFunctionalProgramming<>();
ffp.setT("Xianhuii");
ffp.setLambda((t) -> "Hello " + t + "!");
ffp.doSomeThing();  // Hello Xianhuii!
``````

• 调用处接收一个接口实例`Lambda<T, R>`作为形参。
• 执行`before()`方法，处理相对固定的前处理逻辑。
• 将执行过程中相关值作为形参传给`Lambda<T, R>`实例，进行特定处理。
• 接收`Lambda<T, R>`特定处理后的返回值。
• 执行`after()`方法，处理相对固定的后处理逻辑。

原文作者：Xianuii
原文地址: https://www.cnblogs.com/Xianhuii/p/16927003.html
本文转自网络文章，转载此文章仅为分享知识，如有侵权，请联系博主进行删除。