Java8InAction学习笔记(五) - 18965050/Java8InAction GitHub Wiki

Refactoring

匿名类转换为lambda表达式

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;
	}
}

将必不可少的数据处理转换为Stream

lambda对现有设计模式的影响

lambda表达式对单抽象方法的接口(即函数接口)都可以进行改造, 因此如下模式(包括但不限于)都会受到影响:

  • 策略模式(Strategy)
  • 模板方法模式(Template Method)
  • 观察者模式(Observer)
  • 工厂模式(Factory)

但是, 有多少人或采用lambda表达式的方式来进行模式改造呢???

调试

lambda表达式的使用一个问题就是不利于调试. 一个比较方便的方法是使用Stream.peek()方法

⚠️ **GitHub.com Fallback** ⚠️