1.Lambda优先于匿名类

       Lambda类似于匿名类的函数,但是更加简洁。
       使用Lambda的时候,尽量删除所有Lambda参数的类型,除非它们存在能够让程序变得更加清晰
但是如果一个计算不是自描述的,或者超过了几行,那就不要把他放在一个Lambda中。一行最理想,三行是合理的最大极限。
       千万不要给函数对象使用匿名类,除非必须创建非函数接口的类型的实例。

2.方法引用优先于Lambda

方法应用类型 范例 Lambda等式
静态         Integer::parseInt         str -> Integer.parseInt(str)
有限制         Instant.now()::isAfter         Instance then = Instant.now();t ->then.isAfter(t)
无限制         String::toLowerCase         str->str.toLowerCase()
类构造器         TreeMap<K,V>::now         ()->new TreeMap<.k,v>
数组构造器         int[]::new         len->new int[len]
只要方法引用更加简洁,清晰,就用方法引用,如果方法引用并不简洁,就坚持使用Lambda

3.坚持使用标准的函数接口

       只要标准的函数接口能够满足需求,通常应该优先考虑,而不是专门构建一个新的函数接口。
       基础接口作用于对象引用类型。
Operator接口代表其结果与参数类型一致的函数
Predicate接口代表带有一个参数并但会一个boolean的函数
Function接口代表其参数与返回的类型不一致的函数
Supplier接口代表没有参数并且返回一个值的函数。
Consumer代表的是带有一个函数但不返回任何值的函数
       他们各自还有3种变体,分别可以作用于int,long,double
       千万不要使用带包装类型的基础函数接口代替基本函数接口

4.谨慎使用stream

       在没有显式类型的情况下,仔细命名Lambda参数,这对于Stream pipeline的可读性重要
       最好避免利用Stream来处理char值
       如果实在不确定用stream还是用迭代好,就两种都试试,看看那种更好用。

5.优先选择Stream中无副作用的函数

       forEach操作应该只用于报告Stream计算的结果,而不是执行计算。
       最重要的收集器工厂是toList,toSet,toMap,groupingBy 和joining

6.Stream要优先用collection作为返回类型

       Collection接口是Iterable的一个子类型,它有一个Stream方法,因此提供了迭代和Stream访问,对于公共的,返回序列的方法,Colleciton或者适当的子类型通常是最佳的返回类型,