内置Java 8谓词始终返回true?


Answers:


162

Java 8中没有内置的永远为true和永远为false谓词。最简单的编写方式是

x -> true

x -> false

比较这些

Predicates.alwaysTrue() // Guava

最后是一个匿名的内部类:

new Predicate<Object>() {
    public boolean test(Object x) {
        return true;
    }
}

Guava具有这些内置谓词的原因可能是静态方法调用比匿名内部类具有巨大的语法优势。在Java 8中,lambda语法非常简洁,以至于写出静态方法调用存在语法上的缺点

不过,这只是语法比较。如果存在单个全局始终为真的谓词,则与x -> true散布在多个类中的事件相比(每个事件都将创建自己的谓词实例),则可能具有较小的空间优势。这是您所关心的吗?节省似乎并不引人注目,这可能就是为什么没有首先添加它们的原因。但是可以在将来的发行版中重新考虑。

更新2015-04-24

我们认为除了各种静态的,命名功能,如Predicate.alwaysTrueRunnable.noop等,我们已决定不添加任何更多的在Java SE的未来版本。

当然,具有名称与已写出的lambda的值中有一些值,但是此值很小。我们期望人们将学习如何阅读和书写x -> true() -> { }并且他们的用法将成为习惯用法。甚至Function.identity()超过的价值x -> x也值得怀疑。

重用现有功能而不是评估已写出的lambda在性能上有很小的优势,但是我们希望这些功能的使用量很小,以至于这种优势可以忽略不计,当然不值得API夸大。

Holger在评论中还提到了优化诸如此类的组合函数的可能性Predicate.or。这也被认为是(JDK-8067971),但是被认为有些脆弱并且容易出错,并且发生的频率不高,因此不值得进行努力。

另请参阅此Lambda FAQ条目。


14
有两个问题:首先是简洁。如果(foo)->{return true;}是我能做的最好的事,我想做得更好。但是您提出了x->true,这更好,可以减轻第一个问题。第二个问题是逻辑与静态声明。如果使用x->true,仍然会涉及逻辑,我可能会无意间搞砸了(例如x->!true)。但是使用时Predicate.alwaysTrue(),逻辑错误的空间为零,因为只有一种或两种类似的方法。另外,我免费获得IDE代码完成。x->true几乎可以,但是Predicate.alwaysTrue()由于上述原因,我仍然写了一个方法。
Garret Wilson

10
@GarretWilson但随着Predicate.alwaysTrue()您的加入,您也可能会因意外书写而搞砸Predicate.alwaysFalse()
戴维·康拉德

5
@DavidConrad,当然。我总是有办法犯错,事实上,我一直在不断发明新的错误。;)我不想在这里就琐碎的事情开始争论,但我只想说一点,我的意思是,使用静态方法引用时,我的约束词汇表只有两个选择:alwaysTrue()alwaysFalse()。对于实际的lambda,我有很多变化。基本上,我每次都在重新构造公式。从本质上讲,alwaysTrue()是我想要做什么的语义标签;x->true实际上每次都在重复一次。不是很大,而是一个考虑因素。
Garret Wilson

25
规范的一个大优势Predicate.alwaysTrue()Predicate.alwaysFalse()实例是,他们可以通过合并的方法,如识别Predicate.orPredicate.andPredicate.negate()。这将允许使用进行预初始化PredicatealwaysTrue()并通过合并无谓的过孔来添加谓词and。由于lambda表达式没有对象身份保证,因此可能会失败x->true。顺便说一句,如果我有一个X带有staticmethod 的类y(){return true;},则使用该方法的X::y时间比x->true但更短,但不是真正推荐的方法……
Holger 2014年

10
这个习惯用法 x -> true的缺点是我必须不使用变量。这会造成不必要的大脑负担,并在我的IDE中发出警告。我尝试使用_ -> true,但这是语法错误。Java肯定缺少“未使用的参数”的关键字(阅读:keyletter)。希望类似的东西会出现在Java 9中(或至少:Java,无论我死了之前^^)
kap 2015年

4

没有番石榴

Boolean.TRUE::booleanValue

3
那很有意思。我不确定它是否能完全体现出请求的精神,但它可以为您带来创造力!
Garret Wilson

21
但这不是a Predicate,因为它不需要参数。
佛罗伦萨·纪尧姆

1
它不是谓词,它是方法参考,但它具有简洁明了的优点,并且不要求提及未使用的参数。+1顺便说一句,因为它避免使用具有严重模块化问题的番石榴,因此值得我
赞扬

16
您的方法引用可分配给Supplier <Boolean>,但不能分配给Predicate <T>
DanielK。18年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.