介绍
Lambda表达式是Java SE 8中一个重要的新特性,允许把函数作为一个方法的参数,允许通过表达式来代替功能接口,就和方法一样,lambda表达式提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。本质上Lambda表达式只是一个“语法糖”,由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。
语法格式
1.(parameters) -> expression
OR
2.(parameters) ->{ statements; }
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
简单示例
// 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表达式变量作用域
Lambda表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
public class Tester {
public static void main(String args[]) {
final int num = 1;
Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
s.convert(2); // 输出结果为 3
}
public interface Converter<T1, T2> {
void convert(int i);
}
}
Lambda表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
int num = 1;
Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
s.convert(2);
num = 5;
//报错信息:Local variable num defined in an enclosing scope must be final or effectively final
Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
String first = "";
Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length()); //编译会出错
基本例子
forEach使用
String[] strArr={"test1","test2","test3","test4"};
//不使用lambda例子
for(String str:strArr){
System.out.println(str);
}
//使用lambda后
strArr.forEach(str->System.out.println(str));
匿名类代替使用
//不使用lambda表达式
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
//使用lambda后
btn.setOnAction(event -> System.out.println("Hello World!"));
List的sort排序
String[] strArr={"test1","test2","test3","test4"};
//不使用lambda表达式(使用匿名内部类排序)
Arrays.sort(strArr, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return (s1.compareTo(s2));
}
});
//使用lambda后
Array.sort(strArr,(s1,s2)->s1.compareTo(s2));
实现Runnable接口
/*
*1.new Thread()
*/
//不使用lambda
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
}).start();
//使用lambda
new Thread(()->System.out.println("Hello world !")).start();
/*
*1.Runnable()
*/
//不使用lambda
Runnable runnable= new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
};
//使用lambda后
Runnable runnable=()->System.out.println("Hello world !");
总结
Lambda表达式可以实现在函数式接口(有且仅有一个抽象方法,但是可以有多个非抽象方法的接口)、代替匿名类。简化了编程时的代码量,使我们的代码更加优美,给我们带来了一种函数式编程思想上的转变。
评论区