
上述的函数式接口都归属于 Java 的 函数式编程(Functional Programming) 和 函数式接口(Functional Interfaces) 部分。具体来说,它们位于 Java 8 引入的 java.util.function
包中,旨在提供一组标准的函数式接口,以便在函数式编程风格中使用。
函数式编程和函数式接口
函数式编程
函数式编程是一种编程范式,强调使用数学函数的概念来构建计算机程序。在函数式编程中,函数是一等公民,可以作为参数传递给其他函数,也可以作为函数的返回值。Java 8 引入了对函数式编程的支持,包括 lambda 表达式、方法引用和函数式接口。
留空
函数式接口
函数式接口是 Java 中的一种特殊接口,它只有一个抽象方法(即 SAM,Single Abstract Method)。Java 8 引入了 @FunctionalInterface
注解,用于标记这样的接口。函数式接口可以被 lambda 表达式隐式地实例化。
java.util.function
包
java.util.function
包提供了许多常用的函数式接口,这些接口可以用于各种函数式编程场景。以下是一些关键的包和接口:
java.util.function
包:- 包含了许多预定义的函数式接口,如
Function
、BiFunction
、Consumer
、BiConsumer
、Supplier
、Predicate
、BiPredicate
、UnaryOperator
和BinaryOperator
。 - 这些接口的设计目的是为了简化 lambda 表达式的使用,使代码更加简洁和易读。
常见的函数式接口及其用途
1. Function<T, R>
- 用途:接受一个参数并返回一个结果。
- 主要方法:
R apply(T t)
- 示例:
Function<String, Integer> stringToLength = String::length;
int length = stringToLength.apply("Hello"); // 结果是 5
2. BiFunction<T, U, R>
- 用途:接受两个参数并返回一个结果。
- 主要方法:
R apply(T t, U u)
- 示例:
BiFunction<Integer, Integer, Integer> adder = (a, b) -> a + b;
int result = adder.apply(3, 4); // 结果是 7
3. Consumer<T>
- 用途:接受一个参数,不返回任何结果。
- 主要方法:
void accept(T t)
- 示例:
Consumer<String> printString = System.out::println;
printString.accept("Hello"); // 输出: Hello
4. BiConsumer<T, U>
- 用途:接受两个参数,不返回任何结果。
- 主要方法:
void accept(T t, U u)
- 示例:
BiConsumer<String, Integer> printMessage = (message, count) -> {
for (int i = 0; i < count; i++) {
System.out.println(message);
}
};
printMessage.accept("Hello", 3); // 输出: Hello
// Hello
// Hello
5. Supplier<T>
- 用途:不接受任何参数,返回一个结果。
- 主要方法:
T get()
- 示例:
Supplier<Double> randomSupplier = Math::random;
double randomValue = randomSupplier.get(); // 返回一个随机数
6. Predicate<T>
- 用途:接受一个参数并返回一个布尔值。
- 主要方法:
boolean test(T t)
- 示例:
Predicate<String> isEmpty = String::isEmpty;
boolean result = isEmpty.test(""); // 结果是 true
7. BiPredicate<T, U>
- 用途:接受两个参数并返回一个布尔值。
- 主要方法:
boolean test(T t, U u)
- 示例:
BiPredicate<Integer, Integer> isEqual = (a, b) -> a.equals(b);
boolean result = isEqual.test(3, 3); // 结果是 true
8. UnaryOperator<T>
- 用途:接受一个参数并返回一个相同类型的参数。
- 主要方法:
T apply(T t)
- 示例:
UnaryOperator<Integer> increment = x -> x + 1;
int result = increment.apply(5); // 结果是 6
9. BinaryOperator<T>
- 用途:接受两个相同类型的参数并返回一个相同类型的参数。
- 主要方法:
T apply(T t, T u)
- 示例:
BinaryOperator<Integer> adder = (a, b) -> a + b;
int result = adder.apply(3, 4); // 结果是 7
处理可变参数
对于可变参数(varargs),Java 标准函数式接口并不直接支持。你可以使用 Function
或自定义函数式接口来处理可变参数。
使用 Function<int[], Integer>
处理可变参数
import java.util.function.Function;
public class Calculator {
public static int sum(int... numbers) {
int total = 0;
for (int number : numbers) {
total += number;
}
return total;
}
}
public class Main {
public static void main(String[] args) {
Function<int[], Integer> sumFunction = Calculator::sum;
int result = sumFunction.apply(new int[]{1, 2, 3, 4, 5}); // 结果是 15
System.out.println("Sum: " + result);
}
}
自定义函数式接口处理可变参数
@FunctionalInterface
interface VarArgsFunction {
int apply(int... numbers);
}
public class Calculator {
public static int sum(int... numbers) {
int total = 0;
for (int number : numbers) {
total += number;
}
return total;
}
}
public class Main {
public static void main(String[] args) {
VarArgsFunction sumFunction = Calculator::sum;
int result = sumFunction.apply(1, 2, 3, 4, 5); // 结果是 15
System.out.println("Sum: " + result);
}
}