java判断中表示and_关于java:&&(AND)和|| (或)在IF声明中

我有以下代码:

if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){

partialHits.get(z).put(z, tmpmap.get(z));

}

其中partialHits是HashMap。 如果第一个陈述是真的,会发生什么? Java还会检查第二个声明吗? 因为为了使第一个语句为真,HashMap不应该包含给定的键,所以如果选中第二个语句,我将得到NullPointerException。

所以简单来说,如果我们有以下代码

if(a && b)

if(a || b)

如果a在第一种情况下为假,并且在第二种情况下a为真,那么Java会检查b吗?

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

if (str != null && !str.isEmpty()) {

doSomethingWith(str.charAt(0));

}

或者,反之亦然

if (str == null || str.isEmpty()) {

complainAboutUnusableString();

} else {

doSomethingWith(str.charAt(0));

}

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

是否存在按位比较,因此您可以评估两个表达式?即if(str!= null | str.isEmpty())? (当然这不是一个实际的例子,事实上它是愚蠢的,但你明白了)

只要表达式没有副作用,短路语义在逻辑上等同于完整的评估。也就是说,如果A为真,你就知道A || B是真的,而不必评估B.它唯一能产生差异的是表达式是否有副作用。对于其他运算符,可以使用*和+作为逻辑and和or; ((A?1:0) * (B?1:0)) == 1,((A?1:0) + (B?1:0)) > 0。你甚至可以做xor:((A?1:0) + (B?1:0)) == 1。

@Kezzer:这是真的有点比较吗?我认为它是一个boolean(逻辑)运算符。它与bitwise(整数)运算符不同,尽管具有相同的符号......

想要在'&&'和'||'之间切换的便捷技巧表达式是以这样的方式否定整个表达式:!(str != null && !str.isEmpty())变为:(str !(!=) null !(&&) !(!)str.isEmpty())然后:(str == null || str.isEmpty())因为:!(!=) is == !(&&) is || !(!) eliminates itself其他有用的否定是:!(= !(>) is <=和反之亦然

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

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

在检查参数值之前,单个参数将检查每个参数,而不考虑值。

双重参数将首先检查左参数及其值,如果true(||)或false(&&)保持第二个不变。

声音是否合并?一个简单的例子应该说清楚:

给出所有例子:

String aString = null;

和:

if (aString != null & aString.equals("lala"))

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

if (aString != null && aString.equals("lala"))

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

OR的相同:

if (aString == null | !aString.equals("lala"))

也会引发NullPointerException。

if (aString == null || !aString.equals("lala"))

检查第一个参数并返回true,因此不会检查第二个参数,因为结果是true。

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

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

哦,我也不知道它也会检查布尔值。到目前为止,它只用于位掩码。

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

@Azimuth:非常欢迎你。如果你不知道什么,解决问题的最好方法就是问。

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

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

The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true. [...] At run time, the left-hand operand expression is evaluated first [...] if the resulting value is false, the value of the conditional-and expression is false and the right-hand operand expression is not evaluated. If the value of the left-hand operand is true, then the right-hand expression is evaluated [...] the resulting value becomes the value of the conditional-and expression. Thus, && computes the same result as & on boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

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

The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false. [...] At run time, the left-hand operand expression is evaluated first; [...] if the resulting value is true, the value of the conditional-or expression is true and the right-hand operand expression is not evaluated. If the value of the left-hand operand is false, then the right-hand expression is evaluated; [...] the resulting value becomes the value of the conditional-or expression. Thus, || computes the same result as | on boolean or Boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

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

int x = (y == null) ? 0 : y.getFoo();

没有NullPointerException。

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

做一个简单的测试:

if (true || ((String) null).equals("foobar")) {

...

}

不会抛出NullPointerException!

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

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

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

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

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

是的,布尔表达式的短路评估是所有C类系列中的默认行为。

一个有趣的事实是,Java还使用&和|作为逻辑操作数(它们被重载,int类型,它们是预期的按位运算)来评估表达式中的所有项,这在你需要副作用。

记住这很有趣:例如给定一个返回布尔值的方法changeData(data),然后:if(a.changeData(data)|| b.changeData(data)){doSomething();如果a.changeData()返回true,则不在b上执行changeData,但是如果(a.changeData(data)| b.changeData(data)){doSomething()}在a和b上执行changeData(),甚至如果在返回的true上调用了一个。

不,它不会,Java会短路并在知道结果后停止评估。

这可以追溯到&和&&,|之间的基本区别和||

顺便说一句,你多次执行相同的任务。不确定效率是否是一个问题。你可以删除一些重复。

Z z2 = partialHits.get(req_nr).get(z); // assuming a value cannout be null.

Z z3 = tmpmap.get(z); // assuming z3 cannot be null.

if(z2 == null || z2 < z3){

partialHits.get(z).put(z, z3);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值