Java 函数式编程的核心是通过函数式接口实现函数作为参数传递或作为结果返回。函数式接口只有一个抽象方法,Java 8 通过 @FunctionalInterface
注解来确保接口符合该条件。
1. Function<T, R>
功能:接收一个参数,返回一个结果,通常用于数据转换。
方法:
R apply(T t)
:将 T 类型的参数转换为 R 类型的结果。andThen(Function<? super R, ? extends V> after)
:组合另一个Function
,先执行当前函数,再执行after
。compose(Function<? super V, ? extends T> before)
:组合另一个Function
,先执行before
,再执行当前函数。
适用场景:对象映射、数据转换。
示例:
Function<String, Integer> stringToLength = String::length;
Function<Integer, Integer> square = x -> x * x;
Function<String, Integer> combinedFunction = stringToLength.andThen(square);
System.out.println(combinedFunction.apply("hello")); // 输出: 25
2. BiFunction<T, U, R>
功能:接收两个参数,返回一个结果。适合处理两个输入的转换或操作。
方法:
R apply(T t, U u)
:接收 T 和 U 类型的两个参数,返回 R 类型的结果。andThen(Function<? super R, ? extends V> after)
:组合另一个Function
,先执行当前函数,再执行after
。
适用场景:例如计算两个数的和、将两个对象合并为一个结果。
示例:
BiFunction<Integer, Integer, Integer> sum = Integer::sum;
BiFunction<Integer, Integer, String> sumToString = sum.andThen(String::valueOf);
System.out.println(sumToString.apply(3, 5)); // 输出: 8
3. Consumer<T>
功能:接收一个参数,不返回结果,常用于执行一些副作用操作。
方法:
void accept(T t)
:对参数执行操作,不返回结果。andThen(Consumer<? super T> after)
:组合另一个Consumer
,先执行当前操作,再执行after
。
适用场景:打印输出、修改对象属性、记录日志。
示例:
Consumer<String> printConsumer = System.out::println;
Consumer<String> upperCaseConsumer = s -> System.out.println(s.toUpperCase());
printConsumer.andThen(upperCaseConsumer).accept("hello");
// 输出:
// hello
// HELLO
4. BiConsumer<T, U>
功能:接收两个参数,不返回结果,适合处理两个输入的副作用操作。
方法:
void accept(T t, U u)
:对两个参数执行操作,不返回结果。andThen(BiConsumer<? super T, ? super U> after)
:组合另一个BiConsumer
,先执行当前操作,再执行after
。
适用场景:处理两个输入的场景,如将两个参数打印或组合处理。
示例:
BiConsumer<String, Integer> printBoth = (s, i) -> System.out.println(s + ": " + i);
printBoth.accept("Age", 25); // 输出: Age: 25
5. Supplier<T>
功能:不接收参数,返回一个结果。适合用于延迟生成数据或提供默认值。
方法:
T get()
:获取结果。
适用场景:延迟加载、默认值生成。
示例:
Supplier<Double> randomSupplier = Math::random;
System.out.println(randomSupplier.get()); // 输出: 随机数
6. Predicate<T>
功能:接收一个参数,返回布尔值,用于条件判断。
方法:
boolean test(T t)
:对参数进行条件判断,返回true
或false
。and(Predicate<? super T> other)
:组合另一个Predicate
,两个条件都为true
时返回true
。or(Predicate<? super T> other)
:组合另一个Predicate
,任意一个条件为true
时返回true
。negate()
:返回当前Predicate
的反结果。
适用场景:过滤、条件判断。
示例:
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isPositive = n -> n > 0;
System.out.println(isEven.and(isPositive).test(4)); // 输出: true
System.out.println(isEven.or(isPositive).test(-3)); // 输出: true
7. BiPredicate<T, U>
功能:接收两个参数,返回布尔值,用于条件判断。
方法:
boolean test(T t, U u)
:对两个参数进行条件判断,返回true
或false
。
适用场景:比较两个值,或者根据两个值执行条件判断。
示例:
BiPredicate<String, Integer> lengthGreaterThan = (s, i) -> s.length() > i;
System.out.println(lengthGreaterThan.test("hello", 3)); // 输出: true
8. UnaryOperator<T>
功能:是 Function
的特例,输入输出类型相同,适合用于对输入进行修改和返回同类型的值。
方法:
T apply(T t)
:接收 T 类型的参数,返回修改后的 T 类型值。andThen(UnaryOperator<T> after)
:组合另一个UnaryOperator
,先执行当前操作,再执行after
。compose(UnaryOperator<T> before)
:组合另一个UnaryOperator
,先执行before
操作,再执行当前操作。
适用场景:对输入进行简单的转换和操作,例如数学运算。
示例:
UnaryOperator<Integer> square = x -> x * x;
System.out.println(square.apply(4)); // 输出: 16
9. BinaryOperator<T>
功能:是 BiFunction
的特例,接收两个相同类型的参数,返回一个相同类型的结果。
方法:
T apply(T t1, T t2)
:接收两个相同类型的参数,返回一个相同类型的结果。minBy(Comparator<? super T> comparator)
:返回一个BinaryOperator
,使用给定的比较器比较两个参数并返回较小的一个。maxBy(Comparator<? super T> comparator)
:返回一个BinaryOperator
,使用给定的比较器比较两个参数并返回较大的一个。
适用场景:用于两个相同类型的数据比较、合并、运算等。
示例:
BinaryOperator<Integer> sum = Integer::sum;
System.out.println(sum.apply(3, 7)); // 输出: 10
BinaryOperator<Integer> max = BinaryOperator.maxBy(Integer::compare);
System.out.println(max.apply(3, 7)); // 输出: 7
10. ToIntFunction<T>
功能:接收一个 T 类型参数,返回一个 int
值。常用于从对象中提取整数值。
方法:
int applyAsInt(T t)
:接收 T 类型的参数,返回int
值。
适用场景:将对象映射为整数值,如从字符串中提取长度。
示例:
ToIntFunction<String> stringLengthFunction = String::length;
System.out.println(stringLengthFunction.applyAsInt("Hello")); // 输出: 5
11. ToDoubleFunction<T>
功能:接收一个 T 类型参数,返回一个 double
值。常用于从对象中提取浮点数值。
方法:
double applyAsDouble(T t)
:接收 T 类型的参数,返回double
值。
适用场景:将对象映射为浮点数值,如从对象中提取某个浮点属性。
示例:
ToDoubleFunction<Integer> half = n -> n / 2.0;
System.out.println(half.applyAsDouble(10)); // 输出: 5.0
12. IntPredicate
功能:接收一个 int
参数,返回布尔值。用于对整数进行条件判断。
方法:
boolean test(int value)
:对int
参数进行条件判断。
适用场景:判断整数是否满足某个条件。
示例:
IntPredicate isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4)); // 输出: true
13. IntConsumer
功能:接收一个 int
参数,不返回结果。适合对整数进行某些操作。
方法:
void accept(int value)
:对int
参数执行操作。andThen(IntConsumer after)
:组合另一个IntConsumer
,先执行当前操作,再执行after
。
适用场景:处理或记录 int
类型的数据,比如打印、操作日志等。
示例:
IntConsumer printInt = System.out::println;
IntConsumer doubleAndPrint = i -> System.out.println(i * 2);
printInt.andThen(doubleAndPrint).accept(5);
// 输出:
// 5
// 10
14. IntFunction<R>
功能:接收一个 int
参数,返回一个结果。用于将整数转换为其他类型的对象。
方法:
R apply(int value)
:接收int
参数,返回 R 类型结果。
适用场景:将整数映射为其他对象类型,比如将索引映射到某个值。
示例:
IntFunction<String> intToString = Integer::toString;
System.out.println(intToString.apply(10)); // 输出: "10"
15. IntSupplier
功能:不接收参数,返回一个 int
值。常用于生成整数值。
方法:
int getAsInt()
:获取结果。
适用场景:生成随机数、序列号或延迟生成某个整数值。
示例:
IntSupplier randomInt = () -> (int) (Math.random() * 100);
System.out.println(randomInt.getAsInt()); // 输出: 随机整数
16. LongFunction<R>
功能:接收一个 long
参数,返回一个结果。适合将 long
类型的数据转换为其他类型的对象。
方法:
R apply(long value)
:接收long
参数,返回 R 类型结果。
适用场景:类似于 IntFunction
,但处理的是 long
数据。
示例:
LongFunction<String> longToString = Long::toString;
System.out.println(longToString.apply(100000L)); // 输出: "100000"
17. DoublePredicate
功能:接收一个 double
参数,返回布尔值。用于对浮点数进行条件判断。
方法:
boolean test(double value)
:对double
参数进行条件判断。
适用场景:判断浮点数是否满足某个条件。
示例:
DoublePredicate isPositive = d -> d > 0.0;
System.out.println(isPositive.test(3.14)); // 输出: true
18. DoubleConsumer
功能:接收一个 double
参数,不返回结果。适合对浮点数进行某些操作。
方法:
void accept(double value)
:对double
参数执行操作。andThen(DoubleConsumer after)
:组合另一个DoubleConsumer
,先执行当前操作,再执行after
。
适用场景:类似于 IntConsumer
,但处理的是 double
数据。
示例:
DoubleConsumer printDouble = System.out::println;
DoubleConsumer halfAndPrint = d -> System.out.println(d / 2);
printDouble.andThen(halfAndPrint).accept(8.0);
// 输出:
// 8.0
// 4.0
19. DoubleFunction<R>
功能:接收一个 double
参数,返回一个结果。用于将 double
数据转换为其他类型的对象。
方法:
R apply(double value)
:接收double
参数,返回 R 类型结果。
适用场景:将浮点数映射为其他对象类型。
示例:
DoubleFunction<String> doubleToString = Double::toString;
System.out.println(doubleToString.apply(3.1415)); // 输出: "3.1415"
20. BinaryOperator<T>
功能:接收两个相同类型的参数,返回一个相同类型的结果。是 BiFunction<T, T, T>
的特例,常用于合并或比较两个值。
方法:
T apply(T t1, T t2)
:接收两个相同类型的参数,返回一个相同类型的结果。minBy(Comparator<? super T> comparator)
:返回使用给定比较器的较小值。maxBy(Comparator<? super T> comparator)
:返回使用给定比较器的较大值。
适用场景:合并或比较两个相同类型的对象,例如求最大值或最小值。
示例:
BinaryOperator<Integer> min = BinaryOperator.minBy(Integer::compare);
System.out.println(min.apply(3, 5)); // 输出: 3
总结
Java 函数式编程提供了一系列的函数式接口,覆盖了各种常见的操作场景,如数据转换、条件判断、副作用操作等。通过这些接口,开发者可以更方便地使用 Lambda 表达式进行简洁、高效的编程。这些接口大部分都支持组合操作,如 andThen
和 compose
,使得操作链条更加灵活。
在实际应用中,选择合适的函数式接口可以极大简化代码逻辑,提高可读性与维护性。
评论 (0)