Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
语法
(Type1 param1, Type2 param2, ..., TypeN paramN) -> {
statement1;
statement2;
//.............
return statementM;
}
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语法的简洁紧凑,我们可以和之前的常用语法做个对比:
- 不使用Lambda
public class Test {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5, 6, 7};
List<Integer> arrayList = Arrays.asList(array);
System.out.println("排序前:");
// 遍历集合,我们常用的方法有for循环,增强的for循环,迭代器遍历
for (Integer number : arrayList) {
System.out.print(number + " ");
}
// 将集合内数字降序排序
arrayList.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
System.out.println("\n排序后:");
// 遍历集合
for (Integer number : arrayList) {
System.out.print(number + " ");
}
}
}
- 使用Lambda
public class Test {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5, 6, 7};
List<Integer> arrayList = Arrays.asList(array);
System.out.println("排序前:");
// 遍历集合
arrayList.forEach(x -> System.out.print(x + " "));
// 将集合内数字降序排序
arrayList.sort((o1, o2) -> o2.compareTo(o1));
System.out.println("\n排序后:");
// 遍历集合
arrayList.forEach(x -> System.out.print(x + " "));
}
}
可以很直观地看到,Lambda语法更加简洁紧凑,尤其是对于上例匿名方法Comparator
的使用中可以体现这一点。
输出均为:
排序前:
1 2 3 4 5 6 7
排序后:
7 6 5 4 3 2 1
变量作用域
lambda 表达式只能引用标记了 final
的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
public class Test {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5, 6, 7};
List<Integer> arrayList = Arrays.asList(array);
final int DOUBLE = 2;
arrayList.forEach(x -> System.out.println(x * DOUBLE));
}
}
输出:
2
4
6
8
10
12
14
lambda 表达式的局部变量可以不用声明为 final
,但是必须不可被后面的代码修改(即隐性的具有 final
的语义)
- 隐性的具有
final
的语义
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5, 6, 7};
List<Integer> arrayList = Arrays.asList(array);
int DOUBLE = 2;
arrayList.forEach(x -> System.out.println(x * DOUBLE));
}
}
输出:
2
4
6
8
10
12
14
- 非
final
public class Test {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5, 6, 7};
List<Integer> arrayList = Arrays.asList(array);
int DOUBLE = 2;
arrayList.forEach(x -> System.out.println(x * DOUBLE));
DOUBLE = 3;
}
}
编译时会报错:从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量。
另外,在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
public class Test {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5, 6, 7};
List<Integer> arrayList = Arrays.asList(array);
int first = 1;
arrayList.sort((first, second) -> first.compareTo(second));
arrayList.forEach(x -> System.out.println(x));
}
}
编译时会报错:已在方法 main(java.lang.String[])中定义了变量 first
方法引用
静态方法或实例方法的引用语法:
Class or instance :: method
则上面例子中的遍历并输出集合元素的代码,也可以写为:
public class Test {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5, 6, 7};
List<Integer> arrayList = Arrays.asList(array);
arrayList.forEach(System.out::println);
}
}
构造器引用
语法:
ClassName::new
例子
有一个Cat类:
public class Cat {
private String name;
public Cat(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
有一个nameList
,遍历nameList
,调用Cat
构造函数,生成一个catList
:
import java.util.*;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
String[] array = {"tay", "mere", "amy"};
List<String> nameList = Arrays.asList(array);
List<Cat> cats = getCatList(nameList, Cat::new);
cats.forEach(cat -> System.out.println(cat.getName()));
}
public static List<Cat> getCatList(List<String> nameList, Function<String, Cat> function) {
List<Cat> result = new ArrayList<>();
nameList.forEach(name -> result.add(function.apply(name)));
return result;
}
}
输出:
tay
mere
amy
网友评论