6.8 Java8新增的Lambda表达式 6.8.1 Lambda表达式入门

6.8 Java8新增的Lambda表达式

  • Lambda表达式是Java8的重要更新,
  • Lambda表达式支持将代码块作为方法参数,
  • Lambda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口的实例。

6.8.1 Lambda表达式入门

Lambda表达式替代匿名内部类

接口

1
2
3
4
5
public interface Command
{
// 接口里定义的process()方法用于封装“处理行为”
void process(int[] target);
}

匿名内部类方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class CommandTest {
public static void main(String[] args) {
ProcessArray pa = new ProcessArray();
int[] array = { 3, -4, 6, 4 };
// 处理数组,具体处理行为取决于匿名内部类
pa.process(array, new Command() {
public void process(int[] target) {
int sum = 0;
for (int tmp : target) {
sum += tmp;
}
System.out.println("数组元素的总和是:" + sum);
}
});
}
}

Lambda表达式方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

public class CommandTest2 {
public static void main(String[] args) {
ProcessArray pa = new ProcessArray();
int[] array = { 3, -4, 6, 4 };
// 处理数组,具体处理行为取决于匿名内部类
pa.process(array, (int[] target) -> {
int sum = 0;
for (int tmp : target) {
sum += tmp;
}
System.out.println("数组元素的总和是:" + sum);
});
}
}

当使用Lambda表达式代替匿名内部类创建对象时, Lambda表达式的代码块将会代替实现抽象方法的方法体, Lambda表达式就相当一个匿名方法

lambda表达式的组成

Lambda表达式的主要作用就是代替匿名内部类的烦琐语法。它由三部分组成。

  1. 形参列表。形参列表允许省略形参类型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。
  2. **箭头(->)**。必须通过英文中画线和大于符号组成
  3. 代码块。如果代码块只包含一条语句,
    • Lambda表达式允许省略代码块的花括号,那么这条语句就不要用花括号表示语句结束。
    • Lambda代码块只有一条return语句,甚至可以省略return关键字。
    • Lambda表达式需要返回值,而它的代码块中仅有一条省略了return的语句, Lambda表达式会自动返回这条语句的值。

Lambda表达式简写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

interface Eatable {
void taste();
}

interface Flyable {
void fly(String weather);
}

interface Addable {
int add(int a, int b);
}

public class LambdaQs {
// 调用该方法需要Eatable对象
public void eat(Eatable e) {
System.out.println(e);
e.taste();
}

// 调用该方法需要Flyable对象
public void drive(Flyable f) {
System.out.println("我正在驾驶:" + f);
f.fly("【碧空如洗的晴日】");
}

// 调用该方法需要Addable对象
public void test(Addable add) {
System.out.println("5与3的和为:" + add.add(5, 3));
}

public static void main(String[] args) {
LambdaQs lq = new LambdaQs();
System.out.println("------------------------------------");
// 完整形式
lq.eat(() -> {
System.out.println("苹果的味道不错!");
});
// 简写形式
// Lambda表达式的代码块只有一条语句,可以省略花括号。
lq.eat(() -> System.out.println("苹果的味道不错!"));
System.out.println("------------------------------------");
// 完整形式
lq.drive((weather) -> {
System.out.println("今天天气是:" + weather);
System.out.println("直升机飞行平稳");
});
// 简写形式
// Lambda表达式的形参列表只有一个形参,省略圆括号
lq.drive(weather -> {
System.out.println("今天天气是:" + weather);
System.out.println("直升机飞行平稳");
});
System.out.println("------------------------------------");
// 完整形式
lq.test((a, b) -> {
return a + b;
});
// 简写形式
// Lambda表达式的代码块只有一条语句,省略花括号
// 代码块中只有一条语句,即使该表达式需要返回值,也可以省略return关键字。
lq.test((a, b) -> a + b);
}
}

  • Lambda表达式的代码块只有一行代码时,可以省略代码块的花括号;
  • Lambda表达式的形参列表只有一个形参时,可以省略了形参列表的圆括号;
  • Lambda表达式的代码块中只有一个返回语句时,可以省略花括号和return,直接以返回语句的表达式的计算结果作为返回值。

Lambda表达式实际上将会被当成一个”任意类型”的对象,到底需要当成何种类型的对象,这取决于运行环境的需要。