Lambda 表达式:
-
也可称为闭包,它是推动 Java 8 发布的最重要新特性。
-
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
语法:
lambda 表达式的语法格式如下:
//单表达式
(parameters) -> expression
or
//多声明、语句
(parameters) ->{ statements; }
重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体只包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
例子1:
public class Test {
public static void main(String[] args) {
List appleList = Arrays.asList(
new Apple(20.0, "red"),
new Apple(15.0, "green"),
new Apple(17.0, "red")
);
//stream().filter 过滤出所有苹果颜色为红色的数据
List resultList = appleList.stream().filter(a -> {
return "red".equals(a.getColor());
}).collect(toList());
//(Apple a) ,这里其实不需要括号和参数类型,编译器可以识别,因为只包含一个语句,不需要大括号,并且只有一个表达式返回值,不需要申明return,如下
List resultList = appleList.stream().filter(a -> "red".equals(a.getColor())).collect(toList());
System.out.println(resultList);
}
}
例子2:
// 使用 java 7 排序
private void sortUsingJava7(List names){
Collections.sort(names, new Comparator() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
}
// 使用 java 8 排序,匿名方法直接用lambda表达式
private void sortUsingJava8(List names){
Collections.sort(names, (s1, s2) -> s1.compareTo(s2));
}
变量作用域:
- lambda 表达式只能引用标记了 final 的外层局部变量
- 这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
这里顺便介绍一下::的用法:
- 构造器引用:语法是 Class::new
- 静态方法引用:它的语法是 Class::static_method
- 特定类的任意对象的方法引用 Class::method
- 特定对象的方法引用:它的语法是 Instance::method
如上例子可以改成:
public class Test {
public static void main(String[] args) {
List appleList = Arrays.asList(
new Apple(20.0, "red"),
new Apple(15.0, "green"),
new Apple(17.0, "red")
);
//::表示 Test的isReadApple方法
List redApples = filterApples(appleList, Test::isRedApple);
System.out.println(redApples);
}
//Predicate接受 方法作为入参
public static List filterApples(List appleList, Predicate p) {
List result = new ArrayList<>();
for (Apple apple :
appleList) {
//p.test返回 boolean类型,入参apple作为 isRedApple的入参
if (p.test(apple)) {
result.add(apple);
}
}
return result;
}
public static boolean isRedApple(Apple apple) {
return "red".equals(apple.getColor());
}
}
显然还是Stream的filter简便
例子2:
public class Test {
public static void main(String[] args) {
List appleList = Arrays.asList(
new Apple(20.0, "red"),
new Apple(15.0, "green"),
new Apple(17.0, "red")
);
//对AppleList进行重量排序,比较的是Apple.color属性
List resultList = appleList.stream().sorted(Comparator.comparing(Apple::getWeight).reversed()).collect(toList());
System.out.println(resultList);
}
}