【发布时间】:2020-02-22 01:40:01
【问题描述】:
我有一个名字列表。在第 3 行,我必须将 lambda 表达式的结果转换为 Predicate<String>。我正在阅读的书解释说,为了帮助编译器确定匹配的功能接口是什么,强制转换是必要的。
但是,我不需要在下一行进行这样的转换,因为我不调用 negate()。这有什么区别?我知道negate()这里返回Predicate<String>,但是前面的lambda表达式不一样吗?
List<String> names = new ArrayList<>();
//add various names here
names.removeIf(((Predicate<String>) str -> str.length() <= 5).negate()); //cast required
names.removeIf(((str -> str.length() <= 5))); //compiles without cast
【问题讨论】:
-
...为了帮助编译器确定匹配的功能接口是什么,强制转换是必要的。 无论如何都要回答它。下一行不需要它的原因是推断要简单得多,并且不会在推断接口上进行方法调用。我已经学会了使用涉及泛型的 lambda 函数,它主要是关于在这种情况下的推理,并且显式声明非常安全,例如
Predicate<String> predicate = str -> str.length() <= 5; names.removeIf(predicate.negate()); names.removeIf(predicate); -
@Nathan 对 negate() 的调用难道不应该提供更多的上下文,从而使显式转换的必要性变得更少吗?毕竟,lambda 表达式本来可以引用一个函数而不是一个谓词,但是随后对 negate() 的调用消除了任何歧义的空间。
-
但是,如果
negate()无法推断出作为表达式一部分的 lambda 属性的类型,从而进一步无法确定该表达式表示 @987654328,它会调用什么? @. -
我并不是说 negate() 是必要的。我的最后一行显然没有它。但是,我看不出调用 negate() 会如何突然让编译器混淆函数接口的类型。