Lambda表达式

Lambda表达式

【摘要】Lambda表达式~

前言

没有前言~

lambda表达式概念

概念

λ是希腊字母表中排序第十一位的字母,英语名称为lambda。为了避免匿名内部类定义过多,Java8引入这一新特性。其实质是函数式编程的概念。

语法格式

1
2
3
(params)->expression
(params)->statement
(params)->{statements}

借助Runnable推导演示

普通方式启动线程

比如创建线程时,我们只需要关注线程体(内容),而不需要线程类和结构。先来看一下这个代码。

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
package com.aiz.se.lambda;

/**
* @Description 启动一个线程的一种方法
* @Author ZhangYao
*/
public class StartRun implements Runnable {
/**
* 线程入口
*/
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("喝酸奶");
}
}

public static void main(String[] args) {
new Thread(new StartRun()).start();
for (int i = 0; i < 10; i++) {
System.out.println("吃爆米花");
}
}

}

通过内部类

我们知道一个类如果只是使用一次,我们可以把这个类做成内部类。

1
2
3
4
5
6
7
8
9
10
11
12
13
//静态内部类
static class InnerThread1 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("喝酸奶");
}
}
}

public static void main(String[] args) {
new Thread(new InnerThread1()).start();
}

通过局部内部类

其实我们可以把上面那个类中的类进行挪动,放在一个方法当中。

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
//局部内部类
class InnerThread2 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("喝酸奶");
}
}
}
new Thread(new InnerThread2()).start();
}

通过匿名内部类

1
2
3
4
5
6
7
8
9
//匿名内部类 必须借助接口或者父类
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("喝酸奶");
}
}
}).start();

jdk1.8 lambda

相比匿名内部类省略接口名和方法名,但是,这种方式接口里面只能有一个没有实现的方法。

1
2
3
4
5
6
7
//jdk8使用lambda简化 省略接口名和方法名
new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println("喝酸奶");
}
}
).start();

一般来说比较简单的线程体我们才使用lambda,lambda就是用于简化简单的线程体,jdk8会自己进行推导是Runnable的run()方法。接口中如果有多个没有实现的方法无法则进行推导。

推导总结

通过上面一步一步的推导,我想应该明白了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
package com.aiz.se.lambda;

/**
* @Description Lambda表达式简化线程(只用一次)的使用
* @Author ZhangYao
*/
public class LambdaThread {
//静态内部类
static class InnerThread1 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("喝酸奶");
}
}
}

public static void main(String[] args) {
//静态内部类
new Thread(new InnerThread1()).start();

//局部内部类
class InnerThread2 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("喝酸奶");
}
}
}
new Thread(new InnerThread2()).start();

//匿名内部类 必须借助接口或者父类
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("喝酸奶");
}
}
}).start();

//jdk8使用lambda简化 省略接口名和方法名
new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println("喝酸奶");
}
}
).start();

}
}

lambda的使用

在推导过程中,考虑到只是简单的推导越简单越好,我使用的是线程相关的Runnable的例子,其中的run()方法并未涉及到返回值和参数。其实在我们实际使用过程中需要参数和返回值,下面我就来介绍如何来使用。
自定义一个接口,其中只包含一个未实现的方法,并且该方法有返回值和参数。下面我定义了一个数学运算的接口。

1
2
3
interface MathOperation {
int operation(int a, int b);
}

为了使用上面数学运算的接口,我们需要定义一个操作的方法。

1
2
3
private int operate(int a, int b, MathOperation mathOperation) {
return mathOperation.operation(a, b);
}

下面列出全部代码。

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
package com.aiz.se.lambda;

/**
* @Description 测试Java8 Lambda表达式
* @Author ZhangYao
*/
public class LambdaTester {

/**
* 自定义接口
*/
interface MathOperation {
int operation(int a, int b);
}

/**
* @param a
* @param b
* @param mathOperation
* @return a和b经过某种数学运算MathOperation后的结果
*/
private int operate(int a, int b, MathOperation mathOperation) {
return mathOperation.operation(a, b);
}

public static void main(String[] args) {
LambdaTester tester = new LambdaTester();
//类型声明
MathOperation add = (int a, int b) -> a + b;
//不声明类型
MathOperation sub = (a, b) -> a - b;
// 大括号中的返回语句
MathOperation mul = (int a, int b) -> {
return a * b;
};
// 没有大括号及返回语句
MathOperation div = (int a, int b) -> a / b;

//输出结果
System.out.println("10 + 5 = " + tester.operate(10, 5, add));
System.out.println("10 - 5 = " + tester.operate(10, 5, sub));
System.out.println("10 * 5 = " + tester.operate(10, 5, mul));
System.out.println("10 / 5 = " + tester.operate(10, 5, div));
}
}

注:Lambda 表达式只能用于 functional interface ,而 functional interface 只有一个方法。

经常使用场景

实现Runnable/Comparable/迭代列表/事件监听…

参考

菜鸟教程

结束语

没有结束

评论