前文介绍了 Java 8 新增的 Stream 及其使用方式。本文汇总一下 Stream 各个方法经常用到的函数接口。
Comparator 接口
Comparator 接口定义的抽象方法是 compare 方法,这个方法要求返回两个对象的大小关系。在 Java 8 之前,Comparator 接口仅仅定义了这一个抽象接口,而在 Java 8 中新增了很多静态方法和默认方法。该接口主要用于 max、min 方法。
Java 8 新增的默认方法主要是 reversed 和 thenComparing 方法。reversed 方法用于返回一个相反的 Comparator,比如从大于变为小于。thenComparing 方法用于在比较之后,在进行另一个比较操作。
Java 8 新增的静态方法主要是 comparing 方法,用于根据 lambda 表达式生成一些 Comparator 接口实现。如果把函数接口看成是函数,那么这里就是根据一个传入的函数返回另一个函数,是函数式编程里的高阶函数。
Predicate 接口
Predicate 接口是 Java 8 新增的接口,定义了一个抽象方法 test 来测试一个参数是否符合要求。这个接口主要用于 Stream 的 filter 方法,返回结果为 true 的参数符合过滤要求,返回结果为 false 的参数不符合过滤要求,符合过滤要求的参数放入返回的 Stream 中。
该接口也定义了默认方法和静态方法,and、or 方法返回两个 Predicate 接口测试结果的与、或结果,negate 方法返回测试结果的非结果,isEqual 方法判断两个接口是否相同。
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
Function 接口
Function 接口是 Java 8 新增的接口,定义了一个抽象方法 apply,这个方法用于执行一个操作并返回操作结果,主要用于 Stream 中的 map、flatMap 等方法。apply 方法只接受一个参数,参数和返回值都可以是任意类型。
Function 接口提供了 compose 方法用于在执行自身 apply 方法前先执行另一个 Function 接口,andThen 方法用于在执行自身 apply 方法后再执行另一个 Function 接口,以及 identity 方法用于获得一个返回值与参数相同的 Function 接口。
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
BiFunction 和 BinaryOperator 接口
BinaryOperator 接口是 Java 8 新增的接口,继承了 BiFunction 接口。BiFunction 接口定义了一个抽象方法 apply,用于执行一个操作并返回操作结果,主要用于 Stream 中的 reduce 方法。与 Function 接口相比,这里的 apply 接收两个参数。
BiFunction 接口定义了默认方法 andThen 用于在当前 apply 执行之后执行另一个 Function 接口;BinaryOperator 接口定义了两个静态方法,minBy 方法用于返回两个参数中较小的一个,maxBy 方法用于返回两个参数中较大的一个。
public interface BiFunction<T, U, R> {
R apply(T t, U u);
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
}
每周 3 篇学习笔记或技术总结,面向有一定基础的 Java 程序员,内容涉及 Java 进阶、虚拟机、MySQL、NoSQL、分布式计算、开源框架等多个领域。关注作者或微信公众号 后端开发那点事儿 第一时间获取最新内容。