增加代码的灵活性
有条件if的延迟执行
public static void main(String[] args) {
// 即使内部不调用genString,这里已经调用了genString
print(false, genString());
// genString的调用延迟到内部supplier.get()时候调用
print(false, () -> genString());
}
// 通过Supplier方式实现有条件的延迟加载
public static void print(boolean b, Supplier<String> genString) {
if (b)
System.out.println(genString.get());
}
public static void print(boolean b, String s) {
if (b)
System.out.println(s);
}
public static String genString() {
System.out.println("genString");
return "string";
}
环绕执行模式
// 先定义一个函数式接口
@FunctionalInterface
public interface BufferedReaderProcessor {
String process(...);
}
// 定义模板方法, 之前的函数接口作为参数
public static String processFile(BufferedReaderProcessor p) {
// 开头一堆代码, 比如打开文件
...
// 容易变化的地方调用函数接口的方法
p.process(br);
// 结尾一堆代码,比如关闭文件
...
}
// 不同的场景通过传递不同的业务逻辑lambda,只需要一份模板即可
String oneLine = processFile((BufferedReader br) -> ...);
String twoLine = processFile((BufferedReader br) -> ...);
重构设计模式
策略模式
// 直接new接口,传入lambda实现逻辑,相当于new了实现类
Validator numericValidator = new Validator((String s) -> ...);
Validator lowerValidator = new Validator((String s) -> ...);
boolean b1 = numericValidator.validate("...");
boolean b2 = lowerValidator.validate("...");
模板模式
// 定义模板方法,增加一个Consumer参数,负责变动部分逻辑(当然根据实际场景选择合适类型的函数式接口,本质是参数化行为)
public void processTemplate(int id, Consumer<Code> logicCode) {
XXX xxx = getXXXX(id); // 固定逻辑的模板部分
logicCode.accept(xxx); // 需要变化的部分使用comsumer.accept调用
closeXXX();
}
观察者模式
// 使用lambda表达式,代替繁琐的new 实例化接口对象
f.registerObserver((String tweet) -> {...});
责任链模式
// handler用UnaryOperation表示
UnaryOperation<String> headerProcessing = (String text) -> "From Raoul ... ";
UnaryOperation<String> spellCheckerProcessing = (String text) -> text.replaceAll(...);
// 通过Function串联起handler
Function<String, String> pipeline = headerProcessing.andThen(spellCheckerProcessing);
String result = pipeline.apply("...");