Java 8 四大函数式接口详解
目录
引言
一、函数式接口简介
1.1 什么是函数式接口?
1.2 为什么需要函数式接口?
二、四大函数式接口详解
2.1.1 定义
2.1.2 使用场景
2.1.3 示例
2.1.4 其他方法
2.2.1 定义
2.2.2 使用场景
2.2.3 示例
2.3.1 定义
2.3.2 使用场景
2.3.3 示例
2.3.4 其他方法
2.4.1 定义
2.4.2 使用场景
2.4.3 示例
2.4.4 其他方法
三、总结
引言
Java 8 引入了函数式编程的支持,其中最核心的部分就是函数式接口(Functional Interface)。函数式接口是指只包含一个抽象方法的接口,可以用 Lambda 表达式或方法引用来实现。Java 8 提供了许多内置的函数式接口,其中最常用的四个是:
-
Consumer<T>
:消费型接口 -
Supplier<T>
:供给型接口 -
Function<T, R>
:函数型接口 -
Predicate<T>
:断言型接口
本文将详细介绍这四大函数式接口的使用场景、方法定义以及实际示例,帮助你更好地理解和使用它们。
一、函数式接口简介
1.1 什么是函数式接口?
函数式接口是只有一个抽象方法的接口。Java 8 通过@FunctionalInterface
注解来标识函数式接口。虽然这个注解不是强制性的,但建议使用它来确保接口符合函数式接口的定义。
@FunctionalInterface
public interface MyFunctionalInterface {
void doSomething(); // 只有一个抽象方法
}
1.2 为什么需要函数式接口?
函数式接口的主要目的是支持 Lambda 表达式和方法引用,从而简化代码,使代码更加简洁和易读。通过函数式接口,我们可以将行为(方法)作为参数传递,从而实现更灵活的编程。
二、四大函数式接口详解
2.1 Consumer<T>
:消费型接口
2.1.1 定义
Consumer<T>
表示接受一个输入参数并返回无结果的操作。它的抽象方法是:
void accept(T t);
2.1.2 使用场景
适用于需要对输入参数进行处理但不需要返回结果的场景,例如打印、修改对象状态等。
2.1.3 示例
import java.util.function.Consumer;
public class ConsumerExample {
public static void main(String[] args) {
// 使用 Lambda 表达式实现 Consumer
Consumer<String> printConsumer = (s) -> System.out.println(s);
printConsumer.accept("Hello, Consumer!");
// 使用方法引用实现 Consumer
Consumer<String> printConsumerRef = System.out::println;
printConsumerRef.accept("Hello, Method Reference!");
}
}
2.1.4 其他方法
-
andThen(Consumer<? super T> after)
:组合多个Consumer
,按顺序执行。
Consumer<String> first = (s) -> System.out.println("First: " + s);
Consumer<String> second = (s) -> System.out.println("Second: " + s);
first.andThen(second).accept("Hello");
2.2 Supplier<T>
:供给型接口
2.2.1 定义
Supplier<T>
表示一个无参数但返回一个结果的供给操作。它的抽象方法是:
T get();
2.2.2 使用场景
适用于需要生成或提供数据的场景,例如工厂方法、延迟计算等。
2.2.3 示例
import java.util.function.Supplier;
public class SupplierExample {
public static void main(String[] args) {
// 使用 Lambda 表达式实现 Supplier
Supplier<String> stringSupplier = () -> "Hello, Supplier!";
System.out.println(stringSupplier.get());
// 使用方法引用实现 Supplier
Supplier<Double> randomSupplier = Math::random;
System.out.println(randomSupplier.get());
}
}
2.3 Function<T, R>
:函数型接口
2.3.1 定义
Function<T, R>
表示接受一个输入参数并返回一个结果的函数。它的抽象方法是:
R apply(T t);
2.3.2 使用场景
适用于需要将一个值转换为另一个值的场景,例如数据转换、映射操作等。
2.3.3 示例
import java.util.function.Function;
public class FunctionExample {
public static void main(String[] args) {
// 使用 Lambda 表达式实现 Function
Function<String, Integer> lengthFunction = (s) -> s.length();
System.out.println(lengthFunction.apply("Hello, Function!"));
// 使用方法引用实现 Function
Function<String, String> upperCaseFunction = String::toUpperCase;
System.out.println(upperCaseFunction.apply("hello"));
}
}
2.3.4 其他方法
-
compose(Function<? super V, ? extends T> before)
:组合多个Function
,先执行before
,再执行当前函数。 -
andThen(Function<? super R, ? extends V> after)
:组合多个Function
,先执行当前函数,再执行after
。
Function<String, Integer> lengthFunction = String::length;
Function<Integer, String> toStringFunction = Object::toString;
Function<String, String> composedFunction = lengthFunction.andThen(toStringFunction);
System.out.println(composedFunction.apply("Hello")); // 输出 "5"
2.4 Predicate<T>
:断言型接口
2.4.1 定义
Predicate<T>
表示一个接受输入参数并返回布尔值的断言。它的抽象方法是:
boolean test(T t);
2.4.2 使用场景
适用于需要判断输入参数是否满足条件的场景,例如过滤、验证等。
2.4.3 示例
import java.util.function.Predicate;
public class PredicateExample {
public static void main(String[] args) {
// 使用 Lambda 表达式实现 Predicate
Predicate<String> lengthPredicate = (s) -> s.length() > 5;
System.out.println(lengthPredicate.test("Hello")); // false
System.out.println(lengthPredicate.test("Hello, Predicate!")); // true
// 使用方法引用实现 Predicate
Predicate<String> isEmptyPredicate = String::isEmpty;
System.out.println(isEmptyPredicate.test("")); // true
}
}
2.4.4 其他方法
-
and(Predicate<? super T> other)
:逻辑与操作。 -
or(Predicate<? super T> other)
:逻辑或操作。 -
negate()
:逻辑非操作。
Predicate<String> lengthPredicate = (s) -> s.length() > 5;
Predicate<String> containsPredicate = (s) -> s.contains("Hello");
Predicate<String> combinedPredicate = lengthPredicate.and(containsPredicate);
System.out.println(combinedPredicate.test("Hello, World!")); // true
三、总结
Java 8 的四大函数式接口(Consumer
、Supplier
、Function
、Predicate
)为函数式编程提供了强大的支持。通过它们,我们可以用 Lambda 表达式和方法引用简化代码,实现更灵活和高效的编程。
-
Consumer<T>
:用于处理输入参数,无返回值。 -
Supplier<T>
:用于生成数据,无输入参数。 -
Function<T, R>
:用于将输入参数转换为输出结果。 -
Predicate<T>
:用于判断输入参数是否满足条件。