lambda 简介

Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。

Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。

使用 Lambda 表达式可以使代码变的更加简洁紧凑。

不采用 Lambda 的老方法:

1
2
3
4
5
6
Runnable runnable1=new Runnable(){
@Override
public void run(){
System.out.println("Running without Lambda");
}
};

使用 Lambda:

1
Runnable runnable2=()->System.out.println("Running from Lambda");

函数式接口

函数式接口(functional interface 也叫功能性接口,其实是同一个东西)。简单来说,函数式接口是只包含一个方法的接口。比如 Java 标准库中的java.lang.Runnablejava.util.Comparator都是典型的函数式接口。

java 8 提供 @FunctionalInterface作为注解,这个注解是非必须的,只要接口符合函数式接口的标准(即只包含一个方法的接口),虚拟机会自动判断,但最好在接口上使用注解@FunctionalInterface 进行声明,以免团队的其他人员错误地往接口中添加新的方法。

Java 中的 lambda 无法单独出现,它需要一个函数式接口来盛放,lambda 表达式方法体其实就是函数接口的实现.

1
2
3
4
@FunctionalInterface //添加此注解后,接口中只能有一个抽象方法。
public interface A {
void call();
}

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
public class Java8Tester {

public static void main(String[] args) {
Java8Tester tester = new Java8Tester();

// 类型声明
MathOperation addition = (int a, int b) -> a + b;

// 不用类型声明
MathOperation subtraction = (a, b) -> a - b;

// 大括号中的返回语句
MathOperation multiplication = (int a, int b) -> {
return a * b;
};

// 没有大括号及返回语句
MathOperation division = (int a, int b) -> a / b;

System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
System.out.println("10 / 5 = " + tester.operate(10, 5, division));

// 不用括号
GreetingService greetService1 = message ->
System.out.println("Hello " + message);

// 用括号
GreetingService greetService2 = (message) ->
System.out.println("Hello " + message);

greetService1.sayMessage("World");
greetService2.sayMessage("Google");
}

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

interface GreetingService {
void sayMessage(String message);
}

private int operate(int a, int b, MathOperation mathOperation) {
return mathOperation.operation(a, b);

}
}

使用 Lambda 表达式需要注意以下两点:

  • Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的 Lambda 表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
  • Lambda 表达式免去了使用匿名方法的麻烦,并且给予 Java 简单但是强大的函数化的编程能力。

java8 中接口和抽象类的区别

相同点

  1. 都是抽象类型
  2. 都可以有实现方法(以前接口不行)
  3. 都可以不需要实现类或者继承者去实现所有方法(以前不行,现在接口中默认方法不需要实现者实现)

不同点

  1. 抽象类不可以多重继承,接口可以(无论是多重类型继承还是多重行为继承)
  2. 抽象类和接口所反映出的设计理念不同。其实抽象类表示的是”a-is-a”关系,接口表示的是”a-like-a”关系
  3. 接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值;抽象类中的变量默认是 default 型,其值可以在子类中重新定义,也可以重新赋值

总结:默认方法给予我们修改接口而不破坏原来的实现类的结构提供了便利,目前 java 8 的集合框架已经大量使用了默认方法来改进了