Java8是Java发布以来改动最大的一个版本,其中主要添加了函数式编程、Stream、一些日期处理类。
函数式编程中中新加了一些概念:Lambda表达式、函数式接口、函数引用、默认方法、Optional类等;Stream中提供了一些流式处理集合的方法,并提供了一些归约、划分等类的方法;日期中添加了ZoneDateTime、DataFormat等线程安全的方法类;
一:Lambda(匿名函数)介绍
1.简介(方法作为值传递、纯函数不改变值)
在Java8中引入了函数式编程,可以简化代码逻辑,并将函数作为参数来传递;其原理是在函数上封装了一层,提供了一个语法糖,编译器将lambda表达式解释为函数式接口(除了默认方法,只有一个方法的interface),而利用接口式编程对数据进行操作,下面用List排序来说明老的和新的的不同点:
List<Student> students = new ArrayList<Student>(){{
add(new Student("xx",90));
add(new Student("yy",90));
add(new Student("zz",80));
}};
System.out.println("This is a old example!");
Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
});
System.out.println("This is a lambda example!");
students.sort(Comparator.comparing((Student::getGrade)));
2.原理分析
1)default方法:List直接调用sort方法,是因为在List中添加了default方法,这样可以在不影响List众多的实现类和继承类的前提下,对原有的List进行功能扩充
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
2)方法引用,类名::方法,是Lambda表达式的一个缩写,当传入的函数正好可以直接被对应的方法使用时,使用方法引用来缩写
3)函数式接口,在上面的例子中,Student::getGrade是一个Lambda表达式,Comparator.comparing需要的参数为Function<? super T, ? extends U> keyExtractor,这个Function就是一个函数式接口,JVM会在编译时,将该Lambda表达式翻译成该函数式表达式,所以说Lambda是在Function的基础上封装了一层。
二:Stream简介
1.流是一系列数据项,一次只生成一项,它类似于Unix中的cat、tr等命令,是针对输入的一行一行的流来进行处理,这样可以将操作连贯起来,也方便系统的流水线执行;
Collection主要是为了存储和访问数据,而Stream则主要用于描述对数据的计算。Stream中将迭代等在内部实现,并可以根据Fork/Join根据系统的情况进行性能上的优化;
//("This is a old example!");
Map<Integer, List<Student>> stuByGrade = new HashMap<>();
for(Student stu : students){
Integer grade = stu.getGrade();
List<Student> stuForGrade = stuByGrade.get(grade);
if(stuForGrade == null){
stuForGrade = new ArrayList<>();
stuForGrade.add(stu);
}
}
//("This is a lambda example!");
Map<Integer, List<Student>> stuByGrade2 = students.stream()
.collect(groupingBy(Student::getGrade));
三:Optional类
帮助你避免出现 NullPointer异常。它是一个容器对象,可以包含,也可以不包含一个值。