目录
一、函数式接口
只要接口中只有一个抽象方法,都称为函数式接口。JDK自带的方法都加上了@FunctionalInterface注解标识。
Consumer接口
在Java8新引入容器类:Optional对象,避免空指针异常中的“5、如果需要消费数据,怎么进行呢?”,有提到消费型接口。ifPresent通过重写accecpt方法来实现流的消费。
Student st = null;
Optional<Student> student = Optional.ofNullable(st);
student.ifPresent(new Consumer<Student>() {
@Override
public void accept(Student student) {
}
});
Consumer接口下只有一个抽象方法,返回值是viod,传参T,根据传参进行相应功能的消费。
Function计算转换接口
该接口有一个参数T,也存在返回类型R,在方法中,对传入参数进行计算转换,把结果返回。
Predicate判断接口
在方法中,对传入的参数进行条件判断,返回boolean类型。
常用函数式接口方法
此处省略,具体可在接口下查看方法文档,里面包含具体解释。大致有and、andThen、or、negate等,大致意思可以通过英文判断。
eg:and,指在Predicate中,存在二个判断,当二个条件都返回true时,才返回true。
二、方法引用"::"
在lambda时,如果方法体中只有一个方法的调用的话,可以进一步简化代码。
基本格式为,类名或者对象名::方法名。在idea中,一样可以使用alt + enter快捷键转换。
引用类的静态方法
格式,类名::方法名。
Stream<Student> stream = students.stream();
stream.map(student -> student.getAge())
.map(String :: valueOf); //调用String的静态方法,此时用类名
引用对象的实例方法
格式,对象名::方法名。这行代码调用了某个对象成员方法,并且在抽象方法实现中,都按照顺序传入了这个方法中,才可以使用。
//新建可变字符串对象
StringBuilder sb = new StringBuilder();
stream.map(student -> student.getAge())
.map(String :: valueOf)
.forEach(sb::append); //对象的实例方法
构造器引用
格式,类名::new。方法体只有一行代码,并且调用了某个类的构造方法,重写抽象方法中,所有的参数的传入了这个构造方法中。
//新建可变字符串对象
StringBuilder sb = new StringBuilder(); //不在使用sb对象
stream.map(student -> student.getName())
.map(StringBuilder::new) //构造器引用
以上省略个人更建议alt + enter快捷键,不建议特别考虑和纠结。
三、stream流中计算的注意点
在stream中,如果有很多的就算,当流很大时,涉及自动拆箱、装箱,会带来更多的时间消耗。可以通过mapToInt、mapToLong、mapToDouble、flatMapToInt、flatMapToDouble等转换。
Stream<Student> stream = students.stream();
stream.map(new Function<Student, Integer>() {
@Override
public Integer apply(Student student) {
return student.getAge() + 10; //涉及age的Integer拆箱,加10后的装箱
}})
.mapToInt(new ToIntFunction<Integer>() {
@Override
public int applyAsInt(Integer value) {
return value + 20; // 直接返回int类型,如果后续map、filter存在int计算,可以避免拆装箱
}
})
.map().filter()...等等计算
;
四、并行流
流中存在大量元素时,可以通过并行流提高效率,把任务分给多个线程去执行,通过parallel即可转换为并行流。parallelStream()方法也可以,它包含了将对象转为stream流 && 并行流。
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8,9);
stream.parallel() //转换为了并行流
.peek(new Consumer<Integer>() { //stream api中专门用来调试的方法
@Override
public void accept(Integer integer) {
System.out.println(
"当前线程数:" + Thread.currentThread().getName() + "," +
"当前操作数:" + integer);
}
})
.filter(num -> num > 2)
.get();
五、idea源码英文注释翻译
在设置中,可以通过安装translation插件,实现对源码注释的英文翻译。安装后,需要重启idea。
右键点击,点击Translate Documentation即可将注释翻译为中文。
以上是对函数式接口、方法引用"::"、并行流的相关学习,主打推荐使用快捷键,不要过多的推敲,建议大致明白,会使用工具即可,提升效率。