Java 8 Boolean.logicalOr方法


69

在Java 8中,Boolean添加了类中的新方法。

让我们只谈论其中之一

public static boolean Boolean.logicalOr(boolean a , boolean b)

现在,我的问题是,为什么需要它们?

以下两种情况有什么区别?

boolean result = a || b; 要么 Boolean result = Boolean.logicalOr(a,b);

有什么特别之处Boolean.logicalOr(),我什么时候应该更喜欢一个。


14
javadoc说什么?它是否有@see可能有用的参考?
Sotirios Delimanolis

4
从功能上讲,它们是相同的,但是请不要Boolean.logicalOr(a,b)用您的代码编写。当您使用多种功能相同的方式编写代码时,应始终选择可读性最高的方式。
VGR

这里已经有多个好的答案。我要添加的内容并不能证明一个全新的答案。使用Boolean.logicalOr(a, b)而不是a || b减少需要进行单元测试的分支的数量,从而增加测试代码的覆盖范围。缺点是您通常应该测试所有可能性,而Boolean.logicalOr(a, b)不会强迫您这样做a || b。但是,如果这是您确定不需要测试某些可能性的情况之一,则Boolean.logicalOr可以使您不必为覆盖范围编写毫无意义,荒谬的测试。
加里·谢泼德

Answers:


95

主要是那些方法是为了您的方便,并通过使用lambdas / streams中的方法引用使代码更具可读性。让我们看一个例子:

Stream.of(/* .. some objects .. */)
      .map(/* some function that returns a boolean */)
      .reduce(Boolean::logicalOr);

试图写这个a || b

Stream.of(...)
      .map(...)
      .reduce((a, b) -> a || b); // logicalOr is actually using ||

不那么可读,对不对?

正如Sotirios Delimanolis在评论中所述,您可能还想看看javadoc并关注@see BinaryOperator。或查看功能包摘要javadoc


1
|也可以是逻辑,也可以不是短路。
shmosel

1
我想这更清楚。尽管实际上没有任何区别,因为它直接根据其参数进行操作。
shmosel

2
好吧,它会丢失某种类型的检查...:P如果我们不小心将其更改为整数,|则仍然可以正常工作而不会抱怨,而||不会通过编译
Adrian Shum

1
我已经考虑过一个更复杂的例子。如果大量的||&&作为函数编写,那么在我看来..不如方法引用可读。然后,您可能需要仔细检查自己是否没有忽略!;-)
Roland

1
请注意,这段代码的结果是Optional<Boolean>因为reduce返回一个Optional -在映射为空的情况下为空,因此,如果您想像我一样组合一堆布尔值,则需要做一个final.orElse(...)指定在空集合情况下采用什么值。
丹尼尔·斯卡贝克

52

它与方法引用有关。这样,您也可以||在lambda中使用(逻辑或)运算符。

以这种方式,还有其他新功能,例如Objects.isNulletc。

使用函数引用而不是lambda表达式(例如(a,b) -> a || b)更符合流和lambda的“外观”。
同样,方法引用将产生较少的字节码,因此意味着更快的执行时间(至少一点点)。


1
BiConsumer不返回任何值。为什么BinaryOperator不像在文档中那样使用?
shmosel

18
可能值得注意的是,因为它是一个方法调用,所以您失去的短路行为||
凯文(Kevin)

8
@Kevin:仅当您直接调用它时才有意义,无论如何这都不是预期的用例(如该答案所解释)。如果从中创建函数,则Boolean::logicalOr和之间没有区别(a,b)->a||b,因为对函数求值总是意味着在执行代码之前对所有参数进行求值。
Holger

6
a method reference will produce less byte code, and thus mean faster execution times较小的.class文件,也许;但是一旦字节码由JIT编译为汇编程序,原始字节码变大或变小就没有执行速度。
walen

4
@walen True; 需要进行基准测试以确定执行速度。塞巴斯蒂安,我鼓励你这样做。我的发现是显式lambda比方法参考要快一些,但是与使用int而不是Boolean的简单流减少相比,装箱费用占主导地位。
斯图尔特·马克

2

以下两种情况有什么区别?
布尔结果= a || b; 或布尔结果= Boolean.logicalOr(a,b);

关于上述问题,我想在这里发表我的观点。这是尸体Boolean.logicalOr

  public static boolean logicalOr(boolean paramBoolean1, boolean paramBoolean2)
  {
    return (paramBoolean1) || (paramBoolean2);
  }

因此,我们可以看到它a || b最终正在做。但是,当我们使用Boolean.logicalOr而不是时,它将变为非短路||。因为它将(Boolean.logicalOr)视为与其他逻辑运算符附带的(a || b)不同a || b
示例-:请参考下面的代码段...

public static void main(String[] args) {

    boolean bCheck1 = false, bCheck2 = true, bCheck3 = false;
    System.out.println("bCheck1\t" + "bCheck2\t" + "bCheck3\t" + "checkOR-Result\t" + "checkLogicalOr-Result");

    bCheck1 = true; bCheck2 = true; bCheck3 = true;
    System.out.println(bCheck1 +"\t"+ bCheck2 +"\t"+ bCheck3 +"\t"+ checkOR(bCheck1, bCheck2, bCheck3) + "\t\t" + checkLogicalOr(bCheck1, bCheck2, bCheck3));
    bCheck1 = true; bCheck2 = true; bCheck3 = false;
    System.out.println(bCheck1 +"\t"+ bCheck2 +"\t"+ bCheck3 +"\t"+ checkOR(bCheck1, bCheck2, bCheck3) + "\t\t" + checkLogicalOr(bCheck1, bCheck2, bCheck3));
    bCheck1 = true; bCheck2 = false; bCheck3 = true;
    System.out.println(bCheck1 +"\t"+ bCheck2 +"\t"+ bCheck3 +"\t"+ checkOR(bCheck1, bCheck2, bCheck3) + "\t\t" + checkLogicalOr(bCheck1, bCheck2, bCheck3));
    bCheck1 = true; bCheck2 = false; bCheck3 = false;
    System.out.println(bCheck1 +"\t"+ bCheck2 +"\t"+ bCheck3 +"\t"+ checkOR(bCheck1, bCheck2, bCheck3) + "\t\t" + checkLogicalOr(bCheck1, bCheck2, bCheck3));
    bCheck1 = false; bCheck2 = true; bCheck3 = true;
    System.out.println(bCheck1 +"\t"+ bCheck2 +"\t"+ bCheck3 +"\t"+ checkOR(bCheck1, bCheck2, bCheck3) + "\t\t" + checkLogicalOr(bCheck1, bCheck2, bCheck3));
    bCheck1 = false; bCheck2 = true; bCheck3 = false;
    System.out.println(bCheck1 +"\t"+ bCheck2 +"\t"+ bCheck3 +"\t"+ checkOR(bCheck1, bCheck2, bCheck3) + "\t\t" + checkLogicalOr(bCheck1, bCheck2, bCheck3));
    bCheck1 = false; bCheck2 = false; bCheck3 = true;
    System.out.println(bCheck1 +"\t"+ bCheck2 +"\t"+ bCheck3 +"\t"+ checkOR(bCheck1, bCheck2, bCheck3) + "\t\t" + checkLogicalOr(bCheck1, bCheck2, bCheck3));
    bCheck1 = false; bCheck2 = false; bCheck3 = true;
    System.out.println(bCheck1 +"\t"+ bCheck2 +"\t"+ bCheck3 +"\t"+ checkOR(bCheck1, bCheck2, bCheck3) + "\t\t" + checkLogicalOr(bCheck1, bCheck2, bCheck3));
}

private static boolean checkOR(boolean bCheck1, boolean bCheck2, boolean bCheck3){
    return bCheck1 && bCheck2 || bCheck3;
}

private static boolean checkLogicalOr(boolean bCheck1, boolean bCheck2, boolean bCheck3){
    return bCheck1 && Boolean.logicalOr(bCheck2, bCheck3);
}

以下是结果-:

bCheck1 bCheck2 bCheck3 checkOR-Result  checkLogicalOr-Result
true    true    true    true            true
true    true    false   true            true
true    false   true    true            true
true    false   false   false           false
false   true    true    true            false
false   true    false   false           false
false   false   true    true            false
false   false   true    true            false

我们可以看到,与其他逻辑运算符一起使用时,它会产生不同的结果。因此,需要谨慎使用||over Boolean.logicalOr,反之亦然。显然Boolean.logicalOr比更具可读性||。但是每个都有其重要性,可以按以下方式使用。
if(bCheck1 && bCheck2 || bCheck3)不能替换为,if(bCheck1 && Boolean.logicalOr(bCheck2, bCheck3))
但是替换if(bCheck1 && (bCheck2 || bCheck3))if(bCheck1 && Boolean.logicalOr(bCheck2, bCheck3))绝对是个好主意。


1
条件运算符从左到右执行,但是如果存在“()”,则将具有优先级。因此,您的代码输出是绝对正确的,但与上面的问题无关。请阅读这篇文章以澄清introcs.cs.princeton.edu/java/11precedence。 计算机永远不会给出错误的输出:)
Joy

@Joy我了解运算符的优先级。我给出了关于Boolean.logicalOr()有什么特别之处以及何时应该优先选择一个方面的答案 以下两种情况有什么区别。。我给出了一个非常简单的示例,考虑了尚不了解优先级的任何新手。对于老手来说这可能是徒劳的,但绝对可以帮助任何新手。
Ashish Kumar'2

回答太长,只是说添加函数调用等同于添加方括号。应该缩短它。
jmiserez
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.