1️⃣ 什么是 Functional 接口
定义:在 Java 中,**函数式接口(Functional Interface)**是指 只包含一个抽象方法 的接口。
这种接口可以隐式地用 Lambda 表达式 或 方法引用 来实现。
-
通过
@FunctionalInterface注解可以显式声明一个接口是函数式接口(可选,但推荐)。 -
Java 8 提供了很多预定义的函数式接口在
java.util.function包中。
注意:函数式接口可以有 默认方法 和 静态方法,但 只能有一个抽象方法。
例子:自定义函数式接口
@FunctionalInterface
interface MyFunction {
int operate(int a, int b); // 唯一的抽象方法
// 默认方法可以有
default void printHello() {
System.out.println("Hello");
}
// 静态方法也可以有
static void printStatic() {
System.out.println("Static method");
}
}
使用 Lambda 实现:
public class TestFunctional {
public static void main(String[] args) {
MyFunction add = (a, b) -> a + b;
System.out.println(add.operate(5, 3)); // 输出 8
add.printHello(); // 输出 Hello
}
}
2️⃣ Java 预定义函数式接口
Java 8 的 java.util.function 包提供了丰富的函数式接口,主要有:
| 接口 | 描述 | 核心方法 | 组合方法 |
|---|---|---|---|
Function<T,R> | 接收 T,返回 R | R apply(T t) | andThen(), compose() |
Consumer<T> | 接收 T,返回 void | void accept(T t) | andThen() |
Supplier<T> | 无参数,返回 T | T get() | — |
Predicate<T> | 接收 T,返回 boolean | boolean test(T t) | and(), or(), negate() |
UnaryOperator<T> | 接收 T,返回 T | T apply(T t) | andThen(), compose() |
BinaryOperator<T> | 接收两个 T,返回 T | T apply(T t1, T t2) | andThen() |
BiFunction<T,U,R> | 接收 T、U,返回 R | R apply(T t, U u) | andThen() |
BiConsumer<T,U> | 接收 T、U,返回 void | void accept(T t, U u) | andThen() |
BiPredicate<T,U> | 接收 T、U,返回 boolean | boolean test(T t, U u) | and(), or(), negate() |
2.1 Function<T, R>
@FunctionalInterface
public interface Function<T, R> {
@FunctionalInterface:标记这是一个 函数式接口。
函数式接口的要求:只能有 一个抽象方法。
编译器会检查,防止你增加第二个抽象方法。
T:输入类型
R:输出类型功能:表示一个 从 T 到 R 的映射函数,即接受一个输入,返回一个结果。
2.1.1 核心抽象方法
R apply(T t);
-
唯一的抽象方法,也就是函数式接口的 函数方法。
-
功能:接受一个参数
t,返回一个结果R。 -
这是你用 lambda 实现的地方。
示例
Function<String, Integer> strLength = s -> s.length();
System.out.println(strLength.apply("Hello")); // 5
2.1.2默认方法 compose
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
含义:
-
compose表示 先执行 before,再执行当前函数。 -
before:类型为Function<? super V, ? extends T>,可以把输入 V 转换为当前函数接受的类型 T。 -
返回一个新的函数:
V -> R。
示例
Function<Integer, Integer> timesTwo = x -> x * 2;
Function<String, Integer> strLength = s -> s.length();
// 先获取长度,再乘2
Function<String, Integer> lengthTimesTwo = timesTwo.compose(strLength);
System.out.println(lengthTimesTwo.apply("Hello")); // 10
解释:
-
strLength.apply("Hello")→ 5 -
timesTwo.apply(5)→ 10
2.1.3 默认方法 andThen
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
含义:
-
andThen表示 先执行当前函数,再执行 after。 -
after:类型为Function<? super R, ? extends V>,可以把当前函数输出 R 转换为 V。 -
返回一个新的函数:
T -> V。
示例
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
解释:
-
strLength.apply("Hello")→ 5 -
intToStr.apply(5)→ "Length: 5"
✅ 与 compose 相反:compose 是前置函数,andThen 是后置函数。
2.1.4 静态方法 identity
static <T> Function<T, T> identity() {
return t -> t;
}
含义:
-
返回一个恒等函数:输入什么,输出就是什么。
-
常用于占位函数或者不需要变换的情况。
示例
Function<String, String> identity = Function.identity();
System.out.println(identity.apply("Hello")); // Hello
总结 Function 接口设计思想
| 方法 | 用途 |
|---|---|
apply(T t) | 核心抽象方法,函数式接口的“函数” |
compose(Function<? super V, ? extends T> before) | 组合函数,先执行 before,再执行当前函数 |
andThen(Function<? super R, ? extends V> after) | 组合函数,先执行当前函数,再执行 after |
identity() | 恒等函数,输入返回自身 |
特点:
Function支持 函数组合,非常方便进行函数式链式调用。支持 lambda 或 方法引用,是 Java 8 函数式编程的核心接口之一。
常用方法
import java.util.function.Function;
public class FunctionDemo {
public static void main(String[] args) {
Function<String, Integer> stringLength = s -> s.length();
System.out.println(stringLength.apply("Hello")); // 输出 5
// andThen:先执行当前 Function,再执行另一个 Function
//compose:先执行传入的 Function,再执行当前 Function
Function<Integer, Integer> multiplyBy2 = x -> x * 2;
Function<Integer, Integer> add3 = x -> x + 3;
Function<Integer, Integer> combined1 = multiplyBy2.andThen(add3); // (x*2)+3
Function<Integer, Integer> combined2 = multiplyBy2.compose(add3); // (x+3)*2
System.out.println(combined1.apply(5)); // 13
System.out.println(combined2.apply(5)); // 16
}
}
2.2 Consumer<T>
import java.util.function.Consumer;
public class ConsumerDemo {
public static void main(String[] args) {
Consumer<String> printer = s -> System.out.println(s);
printer.accept("Hello Consumer"); // 输出 Hello Consumer
// andThen
Consumer<String> printer2 = s -> System.out.println(s + "!");
printer.andThen(printer2).accept("Test");
// 输出:
// Test
// Test!
}
}
2.3 Supplier<T>
import java.util.function.Supplier;
import java.util.Random;
public class SupplierDemo {
public static void main(String[] args) {
Supplier<Integer> randomInt = () -> new Random().nextInt(100);
System.out.println(randomInt.get()); // 随机输出 0~99
}
}
2.4 Predicate<T>
import java.util.function.Predicate;
public class PredicateDemo {
public static void main(String[] args) {
Predicate<String> isEmpty = s -> s.isEmpty();
System.out.println(isEmpty.test("")); // true
System.out.println(isEmpty.test("abc")); // false
// and / or / negate
Predicate<String> startsWithA = s -> s.startsWith("A");
Predicate<String> combined = isEmpty.or(startsWithA);
System.out.println(combined.test("Apple")); // true
}
}
2.5 UnaryOperator<T> & BinaryOperator<T>
import java.util.function.UnaryOperator;
import java.util.function.BinaryOperator;
public class OperatorDemo {
public static void main(String[] args) {
UnaryOperator<Integer> square = x -> x * x;
System.out.println(square.apply(5)); // 25
BinaryOperator<Integer> sum = (a, b) -> a + b;
System.out.println(sum.apply(3, 7)); // 10
}
}
3️⃣ 总结
-
函数式接口只允许有一个抽象方法,可以有默认方法和静态方法。
-
Lambda 表达式和方法引用可以直接实现函数式接口。
-
Java 提供丰富的 预定义函数式接口,方便处理常见的函数式场景:
-
Function<T,R>:转换/映射 -
Consumer<T>:消费 -
Supplier<T>:提供值 -
Predicate<T>:判断条件 -
UnaryOperator<T>:一元操作 -
BinaryOperator<T>:二元操作
-
2488

被折叠的 条评论
为什么被折叠?



