[Java 8] Predicate、Consumer、Supplier、Function
1. Predicate
Predicate
是Java中的一个函数式接口,它代表一个输入参数并返回一个布尔值的函数。它通常用于对集合或流中的元素进行条件判断、筛选和过滤操作。
Predicate
接口定义了一个抽象方法:
boolean test(T t);
该方法接受一个泛型参数 T 的输入参数,并返回一个布尔值。当输入参数满足某个条件时,test()方法返回 true,否则返回 false。
Predicate接口还提供了一些默认方法,可以用于组合、取反和链式操作,例如:
and(Predicate<? super T> other):
返回一个组合条件,表示当前条件与另一个条件的逻辑与关系。or(Predicate<? super T> other):
返回一个组合条件,表示当前条件与另一个条件的逻辑或关系。negate():
返回当前条件的取反条件。isEqual(Object targetRef):
返回一个判断对象是否与目标对象相等的条件。
下面是一个简单的示例,演示如何使用Predicate对集合进行筛选:
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class PredicateExample {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 使用 Predicate 筛选偶数
Predicate<Integer> isEven = number -> number % 2 == 0;
List<Integer> evenNumbers = filter(numbers, isEven);
System.out.println(evenNumbers); // 输出: [2, 4, 6, 8, 10]
}
public static <T> List<T> filter(List<T> list, Predicate<T> predicate) {
List<T> filteredList = new ArrayList<>();
for (T item : list) {
if (predicate.test(item)) {
filteredList.add(item);
}
}
return filteredList;
}
}
2. Consumer
Consumer
是Java中的一个函数式接口,用于表示接受单个输入参数并在执行操作后不返回任何结果的操作。它通常用于对集合或流中的元素进行遍历、消费或修改操作。
Consumer
接口定义了一个抽象方法:
void accept(T t);
该方法接受一个泛型参数 T
的输入参数,并在方法体中执行相应的操作,通常是对输入参数进行处理或消费。
Consumer
接口还提供了一些默认方法,可以用于组合操作,例如:
andThen(Consumer<? super T> after):
返回一个组合操作,表示当前操作执行完后再执行另一个操作。
下面是一个简单的示例,演示如何使用Consumer
对集合进行遍历和消费操作:
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class ConsumerExample {
public static void main(String[] args) {
List<String> fruits = List.of("Apple", "Banana", "Orange");
// 使用 Consumer 遍历打印水果名称
Consumer<String> printFruit = fruit -> System.out.println(fruit);
forEach(fruits, printFruit);
// 使用 Consumer 修改水果名称为大写并打印
Consumer<String> toUpperCase = fruit -> System.out.println(fruit.toUpperCase());
forEach(fruits, toUpperCase.andThen(printFruit));
}
public static <T> void forEach(List<T> list, Consumer<T> consumer) {
for (T item : list) {
consumer.accept(item);
}
}
}
在上述示例中,我们定义了两个不同的 Consumer
操作:printFruit
和 toUpperCase
。printFruit
用于打印水果名称,而 toUpperCase
用于将水果名称转换为大写并打印。然后,我们使用 forEach()
方法将这些操作应用于字符串列表 fruits
中的每个元素。
通过使用 Consumer
,我们可以以简洁、可读的方式对集合中的元素进行消费操作,从而实现更灵活和可组合的行为。
3. Supplier
Supplier
是Java中的一个函数式接口,用于表示无参数的函数,它提供一个值或对象的生成器。它通常用于延迟计算或提供默认值的场景。
Supplier
接口定义了一个抽象方法:
T get();
该方法没有参数,返回类型为泛型参数 T
。在方法体中,可以执行相应的逻辑来生成或提供一个值。
下面是一个简单的示例,演示如何使用Supplier
生成随机数和默认值:
import java.util.Random;
import java.util.function.Supplier;
public class SupplierExample {
public static void main(String[] args) {
// 生成随机整数
Supplier<Integer> randomInteger = () -> new Random().nextInt();
System.out.println(randomInteger.get());
// 提供默认字符串
Supplier<String> defaultString = () -> "Default Value";
System.out.println(defaultString.get());
}
}
在上述示例中,我们定义了两个不同的Supplier:randomInteger
和 defaultString
。randomInteger
使用nextInt()
方法生成一个随机整数,而 defaultString
提供一个默认字符串值。然后,我们通过调用 get() 方法来获取生成的随机数和默认字符串。
Supplier
的一个常见用例是在需要延迟计算的场景中,只有在需要时才会执行计算操作。它还可以与其他函数式接口(如Optional
、Stream
等)结合使用,提供缺省值或生成流的元素。
通过使用 Supplier
,我们可以以简洁、可读的方式生成值或对象,从而实现更灵活和可复用的代码。
4. Function
Function
是Java中的一个函数式接口,它表示一个接受一个参数并产生一个结果的函数。它通常用于对输入进行转换、映射或计算操作。
Function
接口定义了一个抽象方法:
R apply(T t);
该方法接受一个泛型参数 T
的输入参数,并返回一个泛型参数 R
的结果。在方法体中,可以执行相应的逻辑来对输入参数进行转换或计算,并返回结果。
Function
接口还提供了一些默认方法,可以用于组合操作,例如:
andThen(Function<? super T, ? extends R> after)
:返回一个组合操作,表示当前操作执行完后再执行另一个操作。compose(Function<? super V, ? extends T> before)
:返回一个组合操作,表示先执行另一个操作,再执行当前操作。
下面是一个简单的示例,演示如何使用Function
对字符串进行转换和计算操作:
import java.util.function.Function;
public class FunctionExample {
public static void main(String[] args) {
// 转换字符串为大写
Function<String, String> toUpperCase = str -> str.toUpperCase();
System.out.println(toUpperCase.apply("hello")); // 输出: HELLO
// 计算字符串的长度
Function<String, Integer> lengthFunction = str -> str.length();
System.out.println(lengthFunction.apply("hello")); // 输出: 5
// 组合操作:转换为大写后获取长度
Function<String, Integer> composedFunction = toUpperCase.andThen(lengthFunction);
System.out.println(composedFunction.apply("hello")); // 输出: 5
}
}
在上述示例中,我们定义了两个不同的 Function
操作:toUpperCase
和 lengthFunction
。toUpperCase
用于将字符串转换为大写形式,而 lengthFunction
用于获取字符串的长度。然后,我们分别应用这些操作,并展示了如何使用 andThen()
方法将它们组合在一起执行。
通过使用 Function
,我们可以以简洁、可读的方式对输入进行转换或计算操作,并返回结果。它在数据处理、转换、映射等场景中非常有用,可以提供更灵活和可组合的函数式编程能力。