Java8函数式接口全攻略
一、接口大白话
1.四大基础接口
Consumer<T>
- 核心方法:void accept(T t);
- 消费者。接受一个输入参数,不返回任何结果的操作。
- 望文生义:你给我啥,我就执行啥,没有结果。
Supplier<T>
- 核心方法: T get();
- 供应商。生成一个指定类型的对象,方法没有参数。
- 望文生义:我也不跟你要,我有啥就给你啥。
Function<T, R>
- 核心方法:R apply(T t);
- 函数。接受一个输入参数,返回一个结果。
- 望文生义:你想要什么,你就得把原料和加工方法告诉我。
Predicate<T>
- 核心方法:boolean test(T t);
- 断言。接受一个输入参数,返回一个布尔值结果。
- 望文生义:是对是错总有一个,事儿你告诉我,我负责出结果。
2. 子接口和派生接口
2.1 Consumer
派生接口:
BiConsumer<T, U>
- 接口说明:接受两个输入参数并且没有返回结果的操作。
- 核心方法:void accept(T t, U u);
2.2 Function
子接口:
UnaryOperator<T>
- 接口说明:接受两个输入参数并且没有返回结果的操作。
- 核心方法:void accept(T t, U u);
派生接口:
IntFunction<R>
- 接口说明:接受一个 int 类型的输入参数,并返回一个指定类型的结果。
- 核心方法:R apply(int value)。
IntUnaryOperator
- 接口说明:接受一个 int 类型的参数并且返回同一类型的结果。
- 核心方法:int applyAsInt(int operand)。
ToDoubleFunction<T>
- 接口说明:接受一个输入参数,并返回一个 double 类型的结果。
- 核心方法:double applyAsDouble(T value)。
ToLongFunction<T>
- 接口说明:接受一个输入参数,并返回一个 long 类型的结果。
- 核心方法: long applyAsLong(T value)。
ToIntFunction<T>
- 接口说明:接受一个输入参数,并返回一个 int 类型的结果。
- 核心方法:int applyAsInt(T value)。
BiFunction<T, U, R>
- 接口说明:接受两个输入参数并且返回结果。
- 核心方法:R apply(T t, U u)。
- 子接口:
BinaryOperator<T>
- 接口说明:接受两个同类型的参数并且返回同一类型的结果。
- 核心方法:T apply(T t1, T t2)。
- 派生接口:
IntBinaryOperator
- 接口说明:接受两个同类型的 int 类型参数并且返回同一类型的结果。
- 核心方法:int applyAsInt(int left, int right)。
2.3 Predicate
派生接口:
IntPredicate
- 接口说明:接受一个 int 类型的参数,返回一个布尔值结果。
- 核心方法: boolean test(int value)。
二、基础接口源码:
1. Consumer
/*
* 该代码定义了一个函数式接口 Consumer,它表示一个接受单个输入参数并且不返回结果的操作。
* Consumer 接口的主要方法是 accept,允许执行具有副作用的操作。
* 此外,接口还提供了 andThen 方法,用于将两个 Consumer 操作串联在一起,使得在执行第一个操作后可以执行第二个操作。
* 如果在执行任何操作时抛出异常,异常将被传递给调用者。
*
* @param <T> 输入操作的类型
*/
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
2. Supplier
package java.util.function;
/*
* 该代码定义了一个函数式接口 Supplier,表示结果的供应者。
* 该接口包含一个方法 get(),用于获取结果。Supplier 接口的实现可以返回一个类型为 T 的结果。
* 该接口没有要求每次调用时返回新的或不同的结果。它是 Java 1.8 引入的。
*/
@FunctionalInterface
public interface Supplier<T> {
T get();
}
3. Predicate
/*
* 该代码定义了一个函数式接口 Predicate,表示一个接受一个参数并返回布尔值的函数。
* 该接口包含一个测试方法 test(T t),以及用于组合多个谓词的默认方法 and、negate 和 or。
* 还提供了一个静态方法 isEqual,用于创建一个谓词,该谓词测试两个参数是否相等。
* 该接口是 Java 8 引入的,位于 java.util.function 包中。
*/
package java.util.function;
import java.util.Objects;
/**
* 表示一个一元谓词(布尔值函数)。
*
* <p>这是一个功能接口,其功能方法是{@link #test(Object)}。
*
* @param <T> 谓词的输入类型
*
* @since 1.8
*/
@FunctionalInterface
public interface Predicate<T> {
/**
* 使用给定的参数评估此谓词。
*
* @param t 输入参数
* @return 如果输入参数符合谓词条件,则返回{@code true},否则返回{@code false}
*/
boolean test(T t);
/**
* 返回一个组合谓词,代表此谓词和另一个谓词的短路逻辑与。
* 当评估组合谓词时,如果此谓词为{@code false},则不会评估{@code other}谓词。
*
* <p>评估任一谓词时抛出的任何异常都会被传递给调用者;
* 如果评估此谓词时抛出异常,则不会评估{@code other}谓词。
*
* @param other 将与此谓词进行逻辑与的谓词
* @return 一个组合谓词,代表此谓词和{@code other}谓词的短路逻辑与
* @throws NullPointerException 如果other为null
*/
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
/**
* 返回一个谓词,表示此谓词的逻辑非。
*
* @return 表示此谓词逻辑非的谓词
*/
default Predicate<T> negate() {
return (t) -> !test(t);
}
/**
* 返回一个组合谓词,代表此谓词和另一个谓词的短路逻辑或。
* 当评估组合谓词时,如果此谓词为{@code true},则不会评估{@code other}谓词。
*
* <p>评估任一谓词时抛出的任何异常都会被传递给调用者;
* 如果评估此谓词时抛出异常,则不会评估{@code other}谓词。
*
* @param other 将与此谓词进行逻辑或的谓词
* @return 一个组合谓词,代表此谓词和{@code other}谓词的短路逻辑或
* @throws NullPointerException 如果other为null
*/
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
/**
* 返回一个谓词,测试两个参数是否根据{@link Objects#equals(Object, Object)}相等。
*
* @param <T> 谓词的参数类型
* @param targetRef 用于比较相等的对象引用,可以为{@code null}
* @return 一个谓词,测试两个参数是否根据{@link Objects#equals(Object, Object)}相等
*/
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
4. Function
/*
* 此代码定义了一个函数式接口 Function,表示接受一个参数并产生一个结果的函数。
* 该接口包含一个抽象方法 apply,允许实现类定义函数的具体行为。
* 还提供了 compose 和 andThen 方法,用于函数的组合,允许在函数调用前后应用其他函数。
* 此外,提供了一个静态方法 identity,返回一个始终返回其输入参数的函数。
* 该接口是 Java 8 引入的,属于 java.util.function 包。
*/
package java.util.function;
import java.util.Objects;
/**
* 代表接受一个参数并生成结果的函数。
*
* 该接口是一个函数式接口,其函数方法是{@link #apply(Object)}。
*
* @param <T> 函数输入的类型
* @param <R> 函数结果的类型
*
* @since 1.8
*/
@FunctionalInterface
public interface Function<T, R> {
/**
* 将此函数应用于给定参数。
*
* @param t 函数参数
* @return 函数结果
*/
R apply(T t);
/**
* 返回一个复合函数,首先将输入应用于{@code before}函数,然后将此函数应用于结果。
* 如果任一函数的评估抛出异常,它将被传递给复合函数的调用者。
*
* @param <V> {@code before}函数和复合函数的输入类型
* @param before 在应用此函数之前应用的函数
* @return 一个复合函数,首先应用{@code before}函数,然后应用此函数
* @throws NullPointerException 如果before为null
*
* @see #andThen(Function)
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 返回一个复合函数,首先将此函数应用于输入,然后将结果应用于{@code after}函数。
* 如果任一函数的评估抛出异常,它将被传递给复合函数的调用者。
*
* @param <V> {@code after}函数和复合函数的输出类型
* @param after 在应用此函数之后应用的函数
* @return 一个复合函数,首先应用此函数,然后应用{@code after}函数
* @throws NullPointerException 如果after为null
*
* @see #compose(Function)
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
/**
* 返回一个总是返回其输入参数的函数。
*
* @param <T> 函数的输入和输出对象的类型
* @return 一个总是返回其输入参数的函数
*/
static <T> Function<T, T> identity() {
return t -> t;
}
}