java8特性 - 图2

排序时候的倒序

  1. employees.sort(
  2. Comparator.comparing(Employee::getGender)
  3. .thenComparing(Employee::getAge)
  4. .reversed()
  5. );
  6. employees.forEach(System.out::println);
  7. //都是正序 ,不加reversed
  8. //都是倒序,最后面加一个reserved
  9. //先是倒序(加reserved),然后正序
  10. //先是正序(加reserved),然后倒序(加reserved)
  • reserved() 会影响前面的 comparing() ,即便已经被 reserved() 过了

函数式接口的特点

  • 接口有且仅有一个抽象方法,如上图的抽象方法compare
  • 允许定义静态非抽象方法
  • 允许定义默认defalut非抽象方法(default方法也是java8才有的,见下文)
  • 允许java.lang.Object中的public方法,如上图的方法equals。
  • FunctionInterface注解不是必须的,如果一个接口符合”函数式接口”定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错

甚至可以说:函数式接口是专门为lambda表达式准备的,lambda表达式是只实现接口中唯一的抽象方法的匿名实现类


default关键字

顺便讲一下default关键字,在java8之前

  • 接口是不能有方法的实现,所有方法全都是抽象方法
  • 实现接口就必须实现接口里面的所有方法

这就导致一个问题:当一个接口有很多的实现类的时候,修改这个接口就变成了一个非常麻烦的事,需要修改这个接口的所有实现类


parallel stream 并行注意点

  • 其背后是共享同一个 ForkJoinPool默认并行度是 CPU 核数 -1
    • 如果集合操作涉及数据密集型的任务,使用这样的配置比较合适
    • 如果集合操作涉及同步 IO 操作的话(比如数据库操作、外部服务调用等
      • 建议自定义一个 ForkJoinPool(或普通线程池)