Shortcut “or-assignment” (|=) operator in Java
我在爪哇有一个很长的比较,我想知道他们中的一个或多个是否是真的。比较字符串很长,很难读取,所以为了可读性,我将其拆分,然后自动使用快捷运算符
1 2 3 4 5 | boolean negativeValue = false; negativeValue |= (defaultStock < 0); negativeValue |= (defaultWholesale < 0); negativeValue |= (defaultRetail < 0); negativeValue |= (defaultDelivery < 0); |
如果任何一个默认值
同样,如果我想执行几个逻辑交叉,我可以使用
换言之,对于
1 2 | b1 |= b2; b1 = b1 | b2; |
逻辑运算符(
& 和| 总是评估两个操作数&& 和|| 有条件地计算右操作数;只有当右操作数的值可能影响二进制运算的结果时,才计算右操作数。这意味着在以下情况下不计算右操作数:&& 的左操作数计算为false 。- (因为无论右操作数的计算结果如何,整个表达式都是
false )
- (因为无论右操作数的计算结果如何,整个表达式都是
|| 的左操作数计算为true 。- (因为无论右操作数的计算结果如何,整个表达式都是
true )
- (因为无论右操作数的计算结果如何,整个表达式都是
所以回到你最初的问题,是的,这个构造是有效的,虽然
有些情况下,需要短路,甚至需要短路,但您的场景不是其中之一。
不幸的是,与其他语言不同,Java没有EDCOX1 29和EDCOX1 30。这是在Java为什么没有条件和条件或操作符的复合赋值版本的问题中讨论的?(&;&;=,=)。
它不是一个"捷径"(或短路)操作员,就像和&;&;那样(如果他们已经知道基于lhs的结果,他们不会评估rhs),但在工作方面它会做你想要做的。
作为区别的一个例子,如果
1 | boolean nullOrEmpty = text == null || text.equals("") |
然而,这不会:
1 2 3 | boolean nullOrEmpty = false; nullOrEmpty |= text == null; nullOrEmpty |= text.equals(""); // Throws exception if text is null |
(很明显,你可以为这个特定的案例做
你只要一句话。它在多行上表示,读起来几乎与您的示例代码完全相同,只是命令性较低:
1 2 3 4 5 | boolean negativeValue = defaultStock < 0 | defaultWholesale < 0 | defaultRetail < 0 | defaultDelivery < 0; |
对于最简单的表达式,使用
这是一篇老文章,但为了给初学者提供一个不同的视角,我想举个例子。
我认为对于类似的复合操作符最常见的用例是
1 2 | int a = 10; // a = 10 a += 5; // a = 15 |
这有什么意义?重点是避免样板文件和消除重复的代码。
因此,下一行的操作完全相同,避免在同一行中键入两次变量
1 | b1 |= b2; |
如果它是关于可读性的,我已经有了将测试数据与测试逻辑分离的概念。代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // declare data DataType [] dataToTest = new DataType[] { defaultStock, defaultWholesale, defaultRetail, defaultDelivery } // define logic boolean checkIfAnyNegative(DataType [] data) { boolean negativeValue = false; int i = 0; while (!negativeValue && i < data.length) { negativeValue = data[i++] < 0; } return negativeValue; } |
这段代码看起来更冗长,更容易解释。甚至可以在方法调用中创建数组,如下所示:
1 2 3 4 5 6 | checkIfAnyNegative(new DataType[] { defaultStock, defaultWholesale, defaultRetail, defaultDelivery }); |
它比"比较字符串"更可读,而且还具有短路的性能优势(以数组分配和方法调用为代价)。
编辑:使用varargs参数可以简单地实现更高的可读性:
方法签名为:
1 | boolean checkIfAnyNegative(DataType ... data) |
电话看起来是这样的:
1 | checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery ); |
尽管对于您的问题来说,它可能是多余的,但guava库与
本质上,比较被转换成对象,打包成一个集合,然后迭代。对于或谓词,第一个真正命中从迭代返回,反之亦然。
||逻辑布尔或按位或
|=按位包含或与赋值运算符
=不短路的原因是它执行的是位或非逻辑或。这就是说:
1 | C |= 2 is same as C = C | 2 |
Java操作员教程
1 2 3 4 | List<Integer> params = Arrays.asList (defaultStock, defaultWholesale, defaultRetail, defaultDelivery); int minParam = Collections.min (params); negativeValue = minParam < 0; |