函数式接口在java.util.function
包,这些接口主要支持Java的Lambda表达式和方法引用特性。使用这些接口可以构建更简洁、更灵活的代码,特别是在使用Streams API, Optional, CompletableFuture等中时非常有用。
下面是这个包中一些核心接口的用法和解释:
Predicate<T>
Predicate<T>
接口接受一个输入参数T
,返回一个布尔值。这个接口通常用于测试对象是否符合某个条件。
Predicate<String> isLongerThan5 = s -> s.length() > 5;
System.out.println(isLongerThan5.test("Hello World")); // 输出 true
应用场景:
过滤集合:在使用Collection
的removeIf
方法移除元素时,或使用Stream
的filter
方法进行过滤时,Predicate
接口常被用于定义过滤逻辑。
Consumer<T>
Consumer<T>
接口包含一个名为accept
的方法,它接受一个输入参数T
,返回类型是void
。这通常用于执行对给定对象的操作。
Consumer<String> print = System.out::println;
print.accept("Hello World"); // 输出 Hello World
应用场景:
集合的遍历:在使用forEach
方法遍历集合或流元素时,Consumer
接口被用于对每个元素执行某些操作。
资源处理:在处理资源对象,如关闭文件或数据库连接时,Consumer
可以定义关闭逻辑。
Function<T,R>
Function<T,R>
接口接受一个输入参数T
,返回一个结果R
。这可以用于将输入对象转换为另一种类型。
Function<String, Integer> length = String::length;
System.out.println(length.apply("Hello World")); // 输出 11
应用场景:
转换对象:在使用Stream
的map
方法将流元素从一种类型转换为另一种类型时,Function
用于定义转换规则。
从对象中提取信息:将对象转换成另一个对象,如获取对象属性,也常见于Collections
的transform
方法。
Supplier<T>
Supplier<T>
是一个无参数的函数式接口,用来提供一个泛型类型的对象实例。
Supplier<Date> dateSupplier = Date::new;
System.out.println(dateSupplier.get()); // 输出当前日期和时间
应用场景:
对象的延迟提供:在需要延迟对象创建,例如使用工厂模式时,Supplier
用于提供新实例。
默认值的提供:在某些操作(如Optional
的orElseGet
方法)期望一个默认值时,可通过Supplier
接口来提供。
BiPredicate<T,U>
BiPredicate<T,U>
接受两个输入参数,返回一个布尔值。可以用于两个输入参数的条件测试。
BiPredicate<Integer, String> condition = (i, s) -> i > 20 && s.startsWith("R");
System.out.println(condition.test(30, "Ruby")); // 输出 true
应用场景:
多参数条件测试:当需要对两个不同的对象进行条件测试的时候,例如在集合的removeIf
方法中,可以使用BiPredicate
。
BiConsumer<T,U>
BiConsumer<T,U>
接口包含一个名为accept
的方法,它接受两个输入参数T
和U
,返回类型是void
。这通常用于对两个给定对象执行操作。
BiConsumer<Integer, String> printBoth = (number, string) -> System.out.printf("Number: %d, String: %s%n", number, string);
printBoth.accept(5, "Apple"); // 输出 Number: 5, String: Apple
应用场景:
遍历Map时的操作:在Map
对象的forEach
方法中,可以使用BiConsumer
来访问键和值并执行操作。
两个相关对象的处理:比如处理对请求和响应或对键值对等。
BiFunction<T,U,R>
BiFunction<T,U,R>
接口接受两个输入参数T
和U
,并返回一个结果R
。这用于对两个不同类型的对象进行操作,并产生一个新的结果对象。
BiFunction<Integer, Integer, String> sumToString = (a, b) -> String.valueOf(a + b);
System.out.println(sumToString.apply(5, 10)); // 输出 15
应用场景:
合并两个值:在需要将两个对象信息合并生成第三个对象时,比如在Map
的compute
方法中,BiFunction
被用于定义生成规则。
多个输入参数的转换:当转换逻辑涉及多个输入参数时,比如计算两个对象的相似度或者对两个数值执行数学运算。
总结
还有一些接口可以在java.util.function
包下查看。这些接口能够显著提高代码的灵活性、可读性和简洁性,特别是在你使用Java 8的Stream API进行集合操作时,它们的价值尤为明显。此外,在复杂的业务逻辑和异步编程中,这些接口同样扮演着至关重要的角色。通过它们提供的功能,可以更方便地进行编程,避免编写大量的样板代码。