Lambda表达式
什么是Lambda表达式
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
简单来说,Lambda表达式就是把一个代码块赋给一个变量。
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
Lambda表达式是怎么演变过来的呢
给变量赋值
//首先来先来一个代码块
public void myDo{
system.out.println("你好");
}
//再来一个变量aBlockOfCode
Object aBlockOfCode;
//将代码块赋给变量)
aBlockOfCode = public void myDo(String str){
system.out.println("你好");
}
对表达式简化,说道简化,就要知道Lambda表达式的一些特征
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
接下来运用这些特征来简化表达式
aBlockOfCode = public void myDo(String str){
system.out.println("你好");
}
//1.不声明类型,既然类型不需要,为了简洁那么修饰符也就是多余的
aBlockOfCode = void myDo(str){
system.out.println("你好");
}
//不需要返回类型会自动判断返回类型
aBlockOfCode = myDo(str){
system.out.println("你好");
}
//因为代码块赋给了变量,所以代码块的函数名也是没有意义的
aBlockOfCode =(str){
system.out.println("你好");
}
//代码块中只有一个语句,可以不用大括号,用->代替
aBlockOfCode =(str)-> system.out.println("你好");
这样我们就算是完成了一个Lambda表达式,那么问题来了aBlockOfCode它是一个什么类型的呢?
在Java 8里面,所有的Lambda的类型都是一个接口,而Lambda表达式本身,也就是”那段代码“,需要是这个接口的实现。这是我认为理解Lambda的一个关键所在,简而言之就是,Lambda表达式本身就是一个接口的实现。
所以这个类应给是这样的
interface MyLambdaInterface{
void doSomeShit(String str);
}
这种只有一个接口函数需要被实现的接口类型,我们叫它”函数式接口“。为了避免后来的人在这个接口中增加接口函数导致其有多个接口函数需要被实现,变成"非函数接口”,我们可以在这个上面加上一个声明@FunctionalInterface, 这样别人就无法在里面添加新的接口函数了:
@FunctionalInterface
interface MyLambdaInterface{
void doSomeShit(String str);
}
那么完整的表达式就是这样的
MyLambdaInterface aBlockOfCode =(str)-> system.out.println("你好");
实例
代码如下
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("Runoob");
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);
}
}
执行以上代码,结果为
$ javac Java8Tester.java
$ java Java8Tester
10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello Runoob
Hello Google
Lambda表达式的运用,要注意一下几点
Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的Lambda表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。