[英]What is the difference between a Predicate and a Function Interface in Java8?
我知道这可能是关于 SO 的一个非常基本的问题,但我想知道 Java8 中的Predicate
和Function
接口之间有什么区别?
Predicate<String> predicateTest = (s)-> s.length() > 5;
System.out.println(predicateTest.test("Predicate"));
Function<String, Boolean> functionTest = str -> str.length()> 5;
System.out.println(functionTest.apply("Function"));
在我的示例中,两者都返回true
。唯一的问题是调用方式不同?
Predicate<T>
和Function<T, R>
区别首先, Predicate<T>
严格来说是一个布尔值函数:
_ _ _ _ _ _ _
| |
T --> | predicate | --> boolean
|_ _ _ _ _ _ _|
而这对于Function<T, R>
不一定是正确的:
_ _ _ _ _ _ _
| |
T --> | function | --> R
|_ _ _ _ _ _ _|
后者使用任何类型的对象,就像Predicate<T>
启用一样,但返回类型可能有所不同。
Predicate<T>
和Function<T, R>
Predicate<T>
的用例是当您需要一个函数,该函数使用一个T
类型的参数并返回一个布尔值。 例如,您可能想要过滤元素流,从满足.filter(predicate).findFirst()
等条件的流中找到第一个元素,或者检查元素是否存在满足某个条件的流,例如anyMatch
、 noneMatch
、 allMatch
等。
Function<T, R>
的用例是当您需要一个使用T
类型参数并将其转换为R
类型的函数时,例如在调用stream.map(func)
。
关于您帖子中的示例片段Predicate<String>
和Function<String, Boolean>
就它们所代表的内容而言是相同的,即它们都代表一个函数,该函数采用String
并返回一个boolean
。 但是,前者避免将返回值从boolean
值装箱为Boolean
而后者则不然。
也就是说,这并不一定意味着您可以在任何可以使用Predicate<String>
也可以使用Function<String, Boolean>
,反之亦然。
例子:
虽然这编译:
Predicate<String> predicate = p -> p.length() == 21;
Stream<String> stream = stringList().stream().filter(predicate);
这不会:
Function<String, Boolean> function = p -> p.length() == 21;
Stream<String> stream = stringList().stream().filter(function);
反之亦然:
虽然这有效:
Function<String, Boolean> function = p -> p.length() == 21;
Stream<Boolean> stream = stringList().stream().map(function);
这不会:
Predicate<String> predicate = p -> p.length() == 21;
Stream<Boolean> stream = stringList().stream().map(predicate);
在这种情况下没有区别,它只与您可以申请的事物有关。 因此,例如allMatch
需要Predicate
,您不能传递Function
,即使逻辑上它们做同样的事情。
Aominè 的回答涵盖了基本差异。 我想补充一点,这两个接口还有不同的专用默认方法,即您可以在任何实现类上调用的方法:
Predicate<T>
Predicate<T> and(Predicate<? super T> other)
- 返回一个组合谓词,表示这个谓词和另一个的短路逻辑 AND。Predicate<T> or(Predicate<? super T> other)
- 返回一个组合谓词,表示这个谓词和另一个的短路逻辑 OR。negate()
- 返回一个谓词,表示该谓词的逻辑否定。Function<T,R>
<V> Function<T,V> andThen(Function<? super R,? extends V> after)
- 返回一个组合函数,该函数首先将此函数应用于其输入,然后将after
函数应用于结果。<V> Function<V,R> compose(Function<? super V,? extends T> before)
- 返回一个组合函数,该函数首先将before
函数应用于其输入,然后将此函数应用于结果。 如您所见, Predicate
具有创建复杂条件的有用方法,很像您在常规if
语句中使用的运算符,而Function
具有支持简单链接的方法。
虽然这是一个旧帖子,但我会为新手总结它们之间的差异
Predicate:要实现条件检查,我们应该使用 Predicate 。
函数:为了执行某些操作并返回一些结果,我们应该去函数
谓词:谓词可以带一个类型参数,表示输入类型或参数类型。
函数:函数可以带2个类型参数第一个代表输入类型参数类型,第二个代表返回类型。
Predicate: Predicate 定义了一个名为 test() 的抽象函数。 使用谓词时,您可以说“测试此条件”或“测试此条件”
函数:函数定义了一个名为 apply() 的抽象函数。 使用功能时,您可以说“应用此功能”或“应用此功能”
谓词:始终返回布尔值。
函数:函数可以返回任何类型的值。
有时人们将谓词称为函数的特殊情况。 它们之间的另一个区别是它们在各自的接口中包含不同类型的默认方法和静态方法。
理论上, Predicate<T>
和Function<T, Boolean>
之间不应该有任何功能差异。 Predicate
只是一个函数,它接受某种类型的对象并返回一个布尔值。 Function
是一个泛化,它可以返回任何类型,而不仅仅是Boolean
的。
Java 内部可能存在使它们不同的实现细节,但它们在理论上应该是相同的。
例如,如果接口只能接受Predicate<String>
,而不是Function<String, Boolean
。
Predicate
只能返回一个boolean
( test()
),而Function
进行转换并且可以返回任何内容( apply()
结果)。
Predicate
用于测试条件。
Function
用于进行转换。
从技术角度来看, Predicate<T>
只是一个函数,它接受一个T
并返回一个布尔原始结果。 但是,从使用的角度来看, Predicate<T>
与Function<T, Boolean>
是完全不同的概念。
我们使用Predicate<T>
来执行过滤操作,例如在流管道中,我们取一个大小为n
的Stream<T>
,使用Predicate<T>
对其进行过滤以获得大小小于或等于的流n
。 同时,流管道中的Function<T, Boolean>
用于执行映射操作,将Stream<T>
转换为Stream<Boolean>
。
如您所见, Predicate<T>
和Function<T, Boolean>
在技术上是相同的(为简单起见,忽略包装Boolean
),但是当放在特定的上下文中(例如流管道)时,情况就完全不同了因为他们中的每一个都扮演着不同的角色。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.