lambda优先于匿名类
lambda函数行数不要超过3行,lambda现在是表示小函数的最佳方法
package codeTemplate.effectiveJava.pojo;
public interface Operation {
double apply(double x, double y);
}
package codeTemplate.effectiveJava.pojo;
public enum BasicOperation implements Operation{
PLUS("+"){
public double apply(double x, double y) {
return x+y;
}
},
MINUS("-"){
public double apply(double x, double y) {
return x-y;
}
};
private final String symbol;
BasicOperation(String symbol) {
this.symbol = symbol;
}
}
使用lambda表达式修改
package codeTemplate.effectiveJava.pojo;
public interface Operation {
}
package codeTemplate.effectiveJava.pojo;
import java.util.function.DoubleBinaryOperator;
public enum BasicOperation implements Operation{
PLUS("+",(x,y)->x+y),
MINUS("-",(x,y)->x-y);
private final String symbol;
private final DoubleBinaryOperator operator;
BasicOperation(String symbol,DoubleBinaryOperator operator) {
this.symbol = symbol;
this.operator = operator;
}
}
方法引用优于lambda表达式
只要方法引用更加简洁、清晰,就用方法引用;如果方法引用并不简洁,即坚持使用lambda
静态方法:方法引用(Integer::parseInt),lambda(str->Integet.parseInt(str))
有限制(接收对象是在方法引用中指定的):方法引用(Instance.new()::inAfter),lambda表达式(Instance then=Instance.new();t->then.isAfter())
无限制(常用于流管道中):方法引用(String::toLowerCase),lambda(str->str->toLowerCase())
类构造器:方法引用(TreeMap<K,V>::new),lambda(()->new TreeMap<K,V>)
数组构造器:方法引用(int[]::new),lambda(len->new int[len])
坚持使用标准的函数接口
基本接口
UnaryOperator接口(无入参操作,返回自身类型),函数签名:T apply(T t) 范例:String::toLowerCase
BinaryOperator接口(两个入参操作,返回自身类型),函数签名: T apply(T t1, T t2),范例:BigInteger::add
Predicate接口(一个入参且返回一个boolean),函数签名:boolean test(T t),范例:Collection::isEmpty
Function<T,R> 接口(入参和返回类型不一致),函数签名:R apply(T t),范例:Arrays::asList
Supplier 接口(没有入参,有一个返回),函数签名:T get(),范例:Instant::now
Consumer接口(一个路才能没有返回),函数签名:void accept(T t),范例:System.out::println
注:必须始终用@FunctionalInterface注解自己编写的函数接口进行标注
谨慎使用Stream
- 滥用Stream会使程序代码更难以读懂和维护
- 在没有显示类型的情况下,仔细命名Lambda参数,增加可读性
- 最好避免利用Stream处理char值
优先选择Stream中无副作用的函数
- 终止操作中的forEach应该只用来报告由Stream执行的计算结果,而不是让它执行计算
- 最重要的收集工厂是toList,toSet,toMap,groupingBy,joining