Java8给我们带来了 Lambda表达式和Stream流式操作,提供了函数式编程和简化批处理操作。可能大家日常使用很多,但是很少去关注Lambda 和 Stream实现。
什么是Lambda
简单来说,编程中提到的 lambda 表达式,通常是指需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。
在Java 8里面,所有的Lambda的类型都是一个接口,而Lambda表达式本身,也就是”那段代码“,需要是这个接口的实现。这是我认为理解Lambda的一个关键所在,简而言之就是,Lambda表达式本身就是一个接口的实现。
基本语法:
(parameters) -> { expression or statements }
示例:
// 无参数, 返回1+2的结果
() -> 1+2;
// 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x;
// 接收2个参数(数字),返回表达式运算的结果
(x, y) -> x + y;
// 多个语句要用大括号包裹, 并且返回值要用return指明
(x, y) -> {
int result = x + y;
System.out.print(result);
return result;
};
@FunctionalInterface 是 Java 8 新加入的一种接口,用于指明该接口类型声明是根据 Java 语言规范定义的函数式接口。Java 8 还声明了一些 Lambda 表达式可以使用的函数式接口,当你注释的接口不是有效的函数式接口时,可以使用 @FunctionalInterface 解决编译层面的错误。
根据定义,函数式接口只能有一个抽象方法,如果你尝试添加第二个抽象方法,将抛出编译时错误。
举一个简单使用的例子,首先定义一个接口:这个接口里面只能有一个函数,接口里是返回值为String类型的方法,那么下面使用它的时候就需要有返回值:
package com.example.lambda;
//函数式接口只能有一个抽象方法,如果你尝试添加第二个抽象方法,将抛出编译时错误
@FunctionalInterface
public interface DoSomethingInterface<T> {
String doSomething(T t);
}
public class LambdaTest {
public static void main(String[] args) {
// t就相当于是接口的具体实现,那么使用 t.doSomeThing("print")就会去调用 t 的匿名函数执行。
// 从这段代码看,如果我们有一个抽象类的具体实现逻辑相对简单不用大段代码的时候,可以使用 Lambda
// 表达式去实现具体的逻辑,这样就不用new 多个类。
DoSomethingInterface<String> t = str -> {
return str;
};
String s = t.doSomething("hello world");
System.out.println(s);
}
}
t就相当于是接口的具体实现,那么使用 t.doSomeThing("hello world")就会去调用 t 的匿名函数执行。从这段代码看,如果我们有一个抽象类的具体实现逻辑相对简单不用大段代码的时候,可以使用 Lambda 表达式去实现具体的逻辑,这样就不用new 多个类。
// 1.1使用匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world1 !");
}
}).start();
// 1.2使用 lambda expression
new Thread(() -> System.out.println("Hello world2 !")).start();