Java8InAction学习笔记(五) - 18965050/Java8InAction GitHub Wiki
lambda表达式内不允许重复定义local变量, 但匿名类可以. 如下代码
int a=2;
Runnable r=()->{
int a=5; //编译不通过
System.out.println("Hello");
};
lambda表达式可能会引起歧义. 比如:
@FunctionalInterface
interface Task{
public void execute();
}
public static void doSomething(Runnable r){ r.run(); }
public static void doSomething(Task a){ r.execute(); }
//采用匿名类调用不会有歧义
doSomething(new Task() {
public void execute() {
System.out.println("Danger danger!!");
}
});
doSomething(()->System.out.println("Danger danger!!")); //存在歧义,编译不通过. 调用哪个?
doSomething((Task)() -> System.out.println("Danger danger!!")); //明确指定采用Task,编译通过
###lambda表达式转换为方法引用 lambda表达式适用于简单的逻辑, 如果逻辑比较复杂, 代码需要写的比较多, 可转换为方法引用.
Map<CaloricLevel, List<Dish>> dishesByCaloricLevel =
menu.stream()
.collect(
groupingBy(dish -> {
if (dish.getCalories() <= 400) return CaloricLevel.DIET;
else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT;
}));
//可转换为
Map<CaloricLevel, List<Dish>> dishesByCaloricLevel =
menu.stream()
.collect(groupingBy(Dish::getCaloricLevel));
public class Dish{
...
public CaloricLevel getCaloricLevel(){
if (this.getCalories() <= 400) return CaloricLevel.DIET;
else if (this.getCalories() <= 700) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT;
}
}
lambda表达式对单抽象方法的接口(即函数接口)都可以进行改造, 因此如下模式(包括但不限于)都会受到影响:
- 策略模式(Strategy)
- 模板方法模式(Template Method)
- 观察者模式(Observer)
- 工厂模式(Factory)
但是, 有多少人或采用lambda表达式的方式来进行模式改造呢???
lambda表达式的使用一个问题就是不利于调试. 一个比较方便的方法是使用Stream.peek()方法