Java8已经发布五年了,但是有的人用着JDK8但写的还是八年前发布的Java7,其中一个最大的区别就是Java8引入了函数式编程。虽说编程没有银弹,但是Java8让Java写的可以更优雅、更容易维护,确实是值得学习的。
Lambda表达式
- javac 根据Lambda 表达式上下文信息就能推断出参数的正确类型,可省略Lambda表达式中的所有参数类型。
- 实现循环的优雅程度:内部迭代 > 迭代器 > for循环
- 惰性求值操作:返回stream;及早求值操作:返回另一个值或者空。与build模式类似
- reduce模式,reduce是max、min的通用模式 - 1 
 2
 3
 4- Object accumulator = initialValue; 
 for(Object element : collection) {
 accumulator = combine(accumulator, element);
 }
- 通过Stream 暴露集合的最大优点在于,它很好地封装了内部实现的数据结构。仅暴露一个Stream接口,用户在实际操作中无论如何使用,都不会影响内部的List或Set。 
- 高阶函数:接收函数作为参数
- 无论何时,将Lambda 表达式传给Stream 上的高阶函数,都应该尽量避免副作用(式获取值而不是变量;使用局部变量,可以不使用final 关键字,但局部变量在既成事实上必须是final 的。唯一的例外是forEach 方法,它是一个终结方法。
类库
- 为了减小装箱类型的性能开销,Stream 类的某些方法对基本类型和装箱类型做了区分。在Java 8 中,仅对Int、Long、Double做了特殊处理,因为它们在数值计算中用得最多,特殊处理后的系统性能提升效果最明显。 - 1 
 2
 3
 4- stream.mapToLong/mapToInt/MapToDouble 
 IntSummaryStatistics trackLengthStats = album.getTracks().stream()
 .mapToInt(track -> track.getLength())
 .summaryStatistics(); // 数值统计
- 虽然Java 在持续演进,但它一直在保持着向后二进制兼容。 
- Java8在增加Collection的stream方法之后,核心类库里的类为了兼容二进制所做的努力:ArrayList增加stream方法
- 默认方法三定律 - 1 
 2
 3
 4
 5
 6
 7- public interface Parent { 
 public void message(String body);
 public default void welcome() {
 message("Parent: Hi!");
 }
 public String getLastMessage();
 }- 类胜于接口。如果在继承链中有方法体或抽象的方法声明,那么就可以忽略接口中定义的方法。
- 子类胜于父类。如果一个接口继承了另一个接口,且两个接口都定义了一个默认方法,那么子类中定义的方法胜出。
- 没有规则三。如果上面两条规则不适用,子类要么需要实现该方法,要么将该方法声明为抽象方法。
 
- Optional对象:使用null 代表值不存在的最大问题在于NullPointerException 1 
 2
 3
 4
 5
 6Optional<String> a = Optional.of("a"); 
 if (a.isPresent())// 先调用isPresent再调用get
 a.get();
 Optional<String> b = Optional.ofNullable(null);
 String str1 = b.orElse("default");
 String str2 = b.orElseGet(() -> {return "defualt2";});
高级集合类和收集器
- 流是否保持顺序排列和集合是否有序相关
- 数据分块 1 
 2
 3Map<Artist, Long> numberOfAlbums = albums.stream().collect(groupingBy(Album::getMusician, counting()));// 计数 
 Map<Artist, List<Album>> nameOfAlbums0 = albums.stream().collect(groupingBy(Album::getMusician));
 Map<Artist, List<String>> nameOfAlbums = albums.stream().collect(groupingBy(Album::getMusician, mapping(Album::getName, toList())));
 
         
        