我在一些人们使用 Predicate
s而不是纯if语句的项目中看到了,如下所示:
int i = 5;
// Option 1
if (i == 5) {
// Do something
System.out.println("if statement");
}
// Option 2
Predicate<Integer> predicate = integer -> integer == 5;
if (predicate.test(i)) {
// Do something
System.out.println("predicate");
}
如果语句,偏爱 Predicate
s的意义是什么?
对于您提供的 exact 示例,使用谓词是一个很大的超杀。编译器,然后运行时将创建:
- 一种方法(de-sugared谓词)
- 一个将实现java.util.predicate
的.Class- 在2
创建的类的实例
所有这些与简单的语句。
以及所有这些用于无状态谓词。如果您的谓词是状态的,则如下:
Predicate<Integer> p = (Integer j) -> this.isJGood(j); // you are capturing "this"
然后,每当您使用此谓词时,都会创建一个新实例(至少在当前的JVM下)。
创建这样的谓词的唯一可行的选项当然是在多个位置重新使用它(例如将参数传递给方法)。
使用谓词使您的代码更加灵活。
您可以编写评估Predicate
的条件,而不是始终检查i == 5
是否始终检查条件,该条件允许您通过不同的Predicate
S实现不同条件。
例如,可以将Predicate
作为参数传递给方法:
public void someMethod (Predicate<Integer> predicate) {
if(predicate.test(i)) {
// do something
System.out.println("predicate");
}
...
}
这是Stream
的filter
方法的工作方式。
使用if语句是最好的(读:大多数性能)检查二进制条件的方法。
对于更复杂的情况,开关语句可能更快。
a Predicate
是Function
的特殊形式。实际上,Java语言架构师以一种允许通用原始类型的方式工作。这将使Predicate<T>
大致相当于Function<T, boolean>
(MODULO测试vs应用方法名称)。
如果一个函数(分别方法)作为参数采用一个或多个函数,我们称其为高阶函数。我们说我们将行为传递给一个函数。这使我们能够创建强大的API。
String result = Match(arg).of(
Case(isIn("-h", "--help"), help()),
Case(isIn("-v", "--version"), version()),
Case($(), cmd -> "unknown command: " + cmd)
);
此示例取自Javaslang,这是一个用于对象功能编程的库Java 8 。
免责声明:我是Javaslang的创建者。
这是一个古老的问题,但是我会尝试一下,因为我自己正在与之抗争...
为了原谅自己对谓词的使用,我做了一个自我规则。
我相信谓词在"逻辑点"的情况下很有用。 - 是不是:叶|角|a:图形|的结尾 - 树|直线,这将使逻辑点有效地"逻辑关节"。
通过它是一个关节(又名节点),它具有一个可重复使用且可变状态的状态,可作为末端的手段。
在流中应该穿越路径的流中,谓词很有用,因为它们在保持流的完整性的同时授予了一定程度的访问,这就是为什么最好的谓词IMO是方法是最小化副作用的方法。
即使最常见的谓词形式是newObject.equal.equal(old),它本身就是双质词,但可以与带有副作用 lambda -> lambda.equal(localCache)
的单个谓词一起使用(因此,这可能是唯一的方法参考的例外规则)。
如果,逻辑是指向不同的体系结构设计或组件的输出/出口点,或者您未编写的代码,或者即使是由您编写的代码,则在其功能方面有所不同,然后我要走了一个if-else。
在反应性编程的情况下,谓词的另一个好处是,多个订户可以使用相同的定义逻辑门。
但是,如果发布者的终点将是一个孤独的订户(如果我要到达的情况,则类似于您的示例),则最好使用IF-ELSE完成逻辑。