&&(AND)和|| (或)在IF声明中

Azi*_*uth 126 java if-statement

我有以下代码:

if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){  
    partialHits.get(z).put(z, tmpmap.get(z));  
}
Run Code Online (Sandbox Code Playgroud)

partialHitsHashMap 在哪里.
如果第一个陈述是真的,会发生什么? Java还会检查第二个声明吗?因为为了使第一个语句为真,HashMap不应该包含给定的键,所以如果选中第二个语句,我会得到NullPointerException.
所以简单来说,如果我们有以下代码

if(a && b)  
if(a || b)
Run Code Online (Sandbox Code Playgroud)

Java会检查第一种情况b是否a为假,a第二种情况是否为真?

And*_*s_D 190

不,它不会被评估.这非常有用.例如,如果您需要测试String是否为空或空,您可以编写:

if (str != null && !str.isEmpty()) {
  doSomethingWith(str.charAt(0));
}
Run Code Online (Sandbox Code Playgroud)

或者,反之亦然

if (str == null || str.isEmpty()) {
  complainAboutUnusableString();
} else {
  doSomethingWith(str.charAt(0));
}
Run Code Online (Sandbox Code Playgroud)

如果我们在Java中没有"短路",我们会在上面的代码行中收到很多NullPointerExceptions.

  • 只要表达式没有副作用,短路语义在逻辑上等同于完整的评估.也就是说,如果A为真,你就知道A || B是真的,而不必评估B.它唯一能产生差异的是表达式是否有副作用.对于其他运算符,可以使用`*`和`+`作为逻辑`和`以及`或`; `((A?1:0)*(B?1:0))== 1`,`((A?1:0)+(B?1:0))> 0`.你甚至可以做`xor`:`((A?1:0)+(B?1:0))== 1`. (5认同)
  • 想要在'&&'和'||'之间切换的便捷技巧 表达式是以这样的方式否定整个表达式:`!(str!= null &&!str.isEmpty())`变为:`(str!(!=)null!(&&)!(!)str. isEmpty())`然后:`(str == null || str.isEmpty())`因为:`!(!=)是==``!(&&)是||``!(!)消除本身`其他有用的否定是:`!(<)是> =``!(>)是<=`而反之亦然 (3认同)

Har*_*ded 65

Java有5种不同的布尔比较运算符:&,&&,|,||,^

&和&&是"和"运算符,| 和|| "或"运算符,^是"xor"

在检查参数值之前,单个参数将检查每个参数,而不考虑值.双重参数将首先检查左参数及其值,if true(||)或false(&&)保持第二个参数不变.声音是否合并?一个简单的例子应该说清楚:

给出所有例子:

 String aString = null;
Run Code Online (Sandbox Code Playgroud)

和:

 if (aString != null & aString.equals("lala"))
Run Code Online (Sandbox Code Playgroud)

在评估完成之前检查这两个参数,并为第二个参数抛出NullPointerException.

 if (aString != null && aString.equals("lala"))
Run Code Online (Sandbox Code Playgroud)

检查第一个参数并返回false,因此不会检查第二个参数,因为结果是false无论如何.

OR的相同:

 if (aString == null | !aString.equals("lala"))
Run Code Online (Sandbox Code Playgroud)

也会引发NullPointerException.

 if (aString == null || !aString.equals("lala"))
Run Code Online (Sandbox Code Playgroud)

检查第一个参数并返回true,因此不会检查第二个参数,因为结果是true无论如何.

XOR无法优化,因为它取决于两个参数.

  • "Java有4种不同的布尔比较运算符:&,&&,|,||"......你忘记了`^`(xor). (3认同)

Pet*_*den 26

不,它不会被检查.此行为称为短路评估,是包括Java在内的许多语言的一项功能.

  • @Azimuth:非常欢迎你.如果你不知道什么,解决问题的最好方法就是问. (2认同)

Cow*_*wan 20

这里的所有答案都很棒,但是,为了说明这些问题的来源,对于这样的问题,最好转到源语言:Java语言规范.

第15:23节,Conditional-And运算符(&&)表示:

&&运算符类似于&(§15.22.2),但仅当其左侧操作数的值为true时才计算其右侧操作数.[...]在运行时,如果结果值为false,则条件和表达式的值为false,并且不评估右侧操作数表达式,则首先计算左侧操作数表达式[...] .如果左侧操作数的值为true,则评估右侧表达式[...]结果值将成为条件和表达式的值.因此,&&计算与布尔操作数相同的结果.它的不同之处仅在于有条件地而不是总是评估右侧操作数表达式.

同样,第15:24节,Conditional-Or运算符(||)表示:

|| 运算符就像| (§15.22.2),但仅当其左侧操作数的值为false时才计算其右侧操作数.[...]在运行时,首先评估左侧操作数表达式; [...]如果结果值为true,则条件或表达式的值为true,并且不评估右侧操作数表达式.如果左侧操作数的值为false,则评估右侧表达式; [...]结果值成为条件或表达式的值.因此,|| 计算与|相同的结果 在布尔或布尔操作数上.它的不同之处仅在于有条件地而不是总是评估右侧操作数表达式.

可能有点重复,但最好确认它们是如何工作的.类似地,条件运算符(?:)仅计算适当的'half'(如果值为true则为左半部分,如果为false则为右半部分),允许使用如下表达式:

int x = (y == null) ? 0 : y.getFoo();
Run Code Online (Sandbox Code Playgroud)

没有NullPointerException.


Rom*_*las 6

不,如果a为真(在or测试中),则不会测试b,因为测试的结果将始终为真,无论b表达式的值是什么.

做一个简单的测试:

if (true || ((String) null).equals("foobar")) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

不会NullPointerException!


aby*_*byx 5

不,不会,一旦知道结果,Java 就会短路并停止计算。


小智 5

这里的短路意味着不会评估第二个条件.

如果A为假,则(A && B)将导致短路.

如果A为真,则(A && B)不会导致短路.

如果A为真,如果(A || B)将导致短路.

如果A为假,则(A || B)不会导致短路.