Java中的快捷方式“or-assignment”(| =)运算符
我在Java中做了很长时间的比较,我想知道它们中的一个或多个是否正确。 比较的string很长,很难阅读,所以我把它分解为可读性,并自动去使用快捷键运算符|=
而不是negativeValue = negativeValue || boolean
negativeValue = negativeValue || boolean
。
boolean negativeValue = false; negativeValue |= (defaultStock < 0); negativeValue |= (defaultWholesale < 0); negativeValue |= (defaultRetail < 0); negativeValue |= (defaultDelivery < 0);
如果任何默认的<something>值为negativeValue
,我预计negativeValue
为true。 这有效吗? 它会做我所期望的吗? 我看不到它在Sun网站或者stackoverflow上提到过,但是Eclipse似乎没有问题,代码编译和运行。
同样,如果我想执行几个逻辑交集,我可以使用&=
而不是&&
?
|=
是布尔逻辑运算符|
的复合赋值运算符( JLS 15.26.2 ) ( JLS 15.22.2 ); 不要与条件或||
混淆 ( JLS 15.24 )。 还有&=
和^=
对应于布尔逻辑&
和^
的复合赋值版本。
换句话说,对于boolean b1, b2
,这两个是等价的:
b1 |= b2; b1 = b1 | b2;
逻辑运算符( &
和|
)与条件对应( &&
和||
)的区别在于前者不是“shortcircuit”。 后者呢。 那是:
-
&
和|
总是评估两个操作数 -
&&
和||
有条件地评估正确的操作数; 只有当它的值可能影响二进制运算的结果时,右操作数才被评估。 这意味着右边的操作数在下列情况下不被评估:-
&&
的左操作数评估为false
- (因为不pipe正确的操作数如何评估,整个expression式都是
false
)
- (因为不pipe正确的操作数如何评估,整个expression式都是
-
||
的左操作数 评估为true
- (因为不pipe操作数是
true
,整个expression式都是true
)
- (因为不pipe操作数是
-
所以回到你原来的问题,是的,这个构造是有效的,而|=
并不完全等同于=
和||
快捷方式 ,它确实计算你想要的。 由于您使用的|=
运算符的右侧是一个简单的整数比较操作,因此|
不短路是微不足道的。
有些情况下,当需要短路或甚至需要,但你的情况不是其中之一。
不幸的是,与其他一些语言不同,Java没有&&=
和||=
。 为什么Java不具有条件语言和条件语言或运算符的复合赋值版本呢? (&& =,|| =) 。
这不是“快捷”(或短路)运营商的方式 和(&)是(如果他们已经知道基于LHS的结果,他们不会评估RHS),但是在工作方面它会做你想要的。
作为差异的一个例子,如果text
为null,那么这个代码就可以了:
boolean nullOrEmpty = text == null || text.equals("")
而这不会:
boolean nullOrEmpty = false; nullOrEmpty |= text == null; nullOrEmpty |= text.equals(""); // Throws exception if text is null
(显然你可以为那个特定的情况做"".equals(text)
– 我只是试图说明原理。)
虽然这可能是你的问题矫枉过正,但番石榴图书馆有一些很好的语法与Predicate
s和Predicate
评估或/和Predicate
s。
实质上,比较转换成对象,打包成一个集合,然后迭代。 对于谓词,第一个真正的命中从迭代返回,反之亦然。
如果是关于可读性,我已经从testing逻辑中获得了分离testing数据的概念。 代码示例:
// 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; }
代码看起来更详细和不言自明。 您甚至可以在方法调用中创build一个数组,如下所示:
checkIfAnyNegative(new DataType[] { defaultStock, defaultWholesale, defaultRetail, defaultDelivery });
它比“比较string”更具可读性,并且具有短路(以数组分配和方法调用为代价)的性能优势。
编辑:通过使用可变参数可以简单地实现更多的可读性:
方法签名将是:
boolean checkIfAnyNegative(DataType ... data)
电话可能是这样的:
checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery );
你可以只有一个声明。 用多行表示,它几乎完全像你的示例代码,只是不太必要:
boolean negativeValue = defaultStock < 0 | defaultWholesale < 0 | defaultRetail < 0 | defaultDelivery < 0;
对于最简单的expression式,使用|
可以比||
更快 因为尽pipe它避免了进行比较,但意味着隐式地使用一个分支,而且可能要贵很多倍。
List<Integer> params = Arrays.asList (defaultStock, defaultWholesale, defaultRetail, defaultDelivery); int minParam = Collections.min (params); negativeValue = minParam < 0;
|| 逻辑布尔OR
| 按位或
| =按位包含的OR和赋值运算符
为什么| =不是shortcircit的原因是因为它执行的是或不是逻辑OR。 也就是说:
C | = 2与C = C |相同 2
Java运算符教程