# 函数式接口
# 概述
只有一个抽象方法的接口称之为函数式接口(SAM Single Abstract Method 单一抽象方法模型)
JDK 的函数式接口都加上了 @FunctionalInterface 注解进行标识。
但是无论是否加上该注解,只要接口中只有一个抽象方法,都是函数式接口
函数式接口可以通过 Lambda 表达式进行转换
例子:
@FunctionalInterface | |
public interface InterfaceEx { | |
// 单一抽象方法 | |
void accept(); | |
} |
# 常用函数式接口
# Consumer 消费接口
对传入的值进行消费
@FunctionalInterface | |
public interface Consumer<T> { | |
/** | |
* Performs this operation on the given argument. | |
* @param t the input argument | |
*/ | |
void accept(T t); | |
default Consumer<T> andThen(Consumer<? super T> after) { | |
Objects.requireNonNull(after); | |
return (T t) -> { accept(t); after.accept(t); }; | |
} | |
} |
# Function 计算转换接口
在方法中对传入的参数计算或转换,将结果返回
@FunctionalInterface | |
public interface Function<T, R> { | |
/** | |
* Applies this function to the given argument. | |
* | |
* @param t the function argument | |
* @return the function result | |
*/ | |
R apply(T t); | |
} |
# 常用默认方法
- and
- or
- ntgate
# 方法引用
使用 Lambda 时,如果方法体中只有一个方法的调用的话,我们可以用方法引用进一步简化代码
# 推荐用法
我们在使用 lambda 时不需要考虑什么时候用方法引用,用哪种方法引用,方法引用的格式是什么。我们只需要在写完 lambda 方法发现方法体只有一行代码,并且是方法的调用时使用快捷键尝试是否能够转换成方法引用即可。
当我们方法引用使用的多了慢慢的也可以直接写出方法引用。
# 基本格式
ClassName::Method
# 语法详解
# 引用静态方法
格式: 类名::方法名
使用条件:
- 重写方法时,方法体只有一行代码
- 这行代码调用了某个类的静态方法
- 要重写的抽象方法中所有的参数都按照顺序传入了这个静态方法
例如:
Optional<List<Book>> books = author.map(Author::getBooks); |
# 引用对象实例方法
格式: 对象名::方法名
使用条件:
- 重写方法时,方法体中只有一行代码
- 这行代码是调用了某个对象的成员方法
- 要重写的抽象方法中所有的参数都按照顺序传入了这个成员方法中
StringBuilder stringBuilder = new StringBuilder();; | |
author.stream().map(Author::getName) | |
.forEach(name -> stringBuilder.append(name)); |
StringBuilder stringBuilder = new StringBuilder();
author.stream().map(Author::getName)
.forEach(stringBuilder::append);
# 引用类的实例方法
格式: 类名::方法名
使用条件:
- 重写方法时,方法体只有一行代码
- 这行代码调用了第一个参数的成员方法
- 要重写的抽象方法中剩余所有的参数都按照顺序传入了这个成员方法
# 构造器引用
格式: 类名::new
使用条件:
- 重写方法时,方法体只有一行代码
- 方法调用了某个类的构造方法
- 要重写的抽象方法中所有的参数都按照顺序传入了这个构造方法
# 基本类型优化
对于流的 map () 可以使用 mapToInt 等等以及 flatMapToInt () 去处理基本类型相关可以减少装箱拆箱带来的时间成本。
# 并行流
当流中有大量元素时,我们可以使用并行流来提高操作效率。其实并行流就是把任务分配给多个线程去完成,如果我们自己去用代码实现会非常复杂,并且要求对并发编程有足够理解、
parallel 方法可以把串行流转换成并行流。
public void my() { | |
Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20); | |
Integer sum = stream.parallel() | |
.peek(num -> System.out.println(num+Thread.currentThread().getName())).filter(num-> num>10) | |
.reduce(Integer::sum) | |
.orElse(-1); | |
System.out.println(sum); | |
} |
也可以通过 parallelStream 直接获取并行流对象