Java 中的快捷“或赋值”(|=)运算符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2486472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shortcut "or-assignment" (|=) operator in Java
提问by David Mason
I have a long set of comparisons to do in Java, and I'd like to know if one or more of them come out as true. The string of comparisons was long and difficult to read, so I broke it up for readability, and automatically went to use a shortcut operator |=
rather than negativeValue = negativeValue || boolean
.
我要在 Java 中进行一长串比较,我想知道其中一个或多个是否正确。比较字符串很长且难以阅读,因此我将其拆分以提高可读性,并自动使用快捷操作符|=
而不是negativeValue = negativeValue || boolean
.
boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);
I expect negativeValue
to be true if any of the default<something> values are negative. Is this valid? Will it do what I expect? I couldn't see it mentioned on Sun's site or stackoverflow, but Eclipse doesn't seem to have a problem with it and the code compiles and runs.
negativeValue
如果任何默认<something> 值为负,我希望为真。这是有效的吗?它会做我期望的事情吗?我在 Sun 的网站或 stackoverflow 上看不到它提到它,但 Eclipse 似乎没有问题,并且代码编译并运行。
Similarly, if I wanted to perform several logical intersections, could I use &=
instead of &&
?
同样,如果我想执行几个逻辑交集,我可以使用&=
而不是&&
吗?
采纳答案by polygenelubricants
The |=
is a compound assignment operator (JLS 15.26.2) for the boolean logical operator |
(JLS 15.22.2); not to be confused with the conditional-or ||
(JLS 15.24). There are also &=
and ^=
corresponding to the compound assignment version of the boolean logical &
and ^
respectively.
的|=
是这样的化合物赋值运算符(JLS 15.26.2为布尔逻辑运算符)|
(JLS 15.22.2); 不要与条件或||
(JLS 15.24)混淆。还有&=
和分别^=
对应于布尔逻辑&
和的复合赋值版本^
。
In other words, for boolean b1, b2
, these two are equivalent:
换句话说,对于boolean b1, b2
,这两个是等价的:
b1 |= b2;
b1 = b1 | b2;
The difference between the logical operators (&
and |
) compared to their conditional counterparts (&&
and ||
) is that the former do not "shortcircuit"; the latter do. That is:
(逻辑运算符之间的差异&
和|
)相比,他们的条件同行(&&
和||
)之处在于前者不“短路”; 后者做。那是:
&
and|
alwaysevaluate both operands&&
and||
evaluate the right operand conditionally; the right operand is evaluated only if its value could affect the result of the binary operation. That means that the right operand is NOT evaluated when:- The left operand of
&&
evaluates tofalse
- (because no matter what the right operand evaluates to, the entire expression is
false
)
- (because no matter what the right operand evaluates to, the entire expression is
- The left operand of
||
evaluates totrue
- (because no matter what the right operand evaluates to, the entire expression is
true
)
- (because no matter what the right operand evaluates to, the entire expression is
- The left operand of
&
并|
始终评估两个操作数&&
并有条件地||
评估正确的操作数;只有当它的值可能影响二元运算的结果时,才计算正确的操作数。这意味着在以下情况下不会评估正确的操作数:- 的左操作数
&&
计算为false
- (因为无论正确的操作数计算为什么,整个表达式都是
false
)
- (因为无论正确的操作数计算为什么,整个表达式都是
- 的左操作数
||
计算为true
- (因为无论正确的操作数计算为什么,整个表达式都是
true
)
- (因为无论正确的操作数计算为什么,整个表达式都是
- 的左操作数
So going back to your original question, yes, that construct is valid, and while |=
is not exactly an equivalent shortcut for =
and ||
, it does compute what you want. Since the right hand side of the |=
operator in your usage is a simple integer comparison operation, the fact that |
does not shortcircuit is insignificant.
所以回到你原来的问题,是的,结构是有效的,虽然|=
是不完全的等价快捷=
和||
,这你想要做什么的计算。由于|=
您使用的运算符右侧是一个简单的整数比较运算,因此|
不短路这一事实无关紧要。
There are cases, when shortcircuiting is desired, or even required, but your scenario is not one of them.
在某些情况下,需要或什至需要短路,但您的情况不是其中之一。
It is unfortunate that unlike some other languages, Java does not have &&=
and ||=
. This was discussed in the question Why doesn't Java have compound assignment versions of the conditional-and and conditional-or operators? (&&=, ||=).
不幸的是,与其他一些语言不同,Java 没有&&=
和||=
。这在问题为什么 Java 没有条件和和条件或运算符的复合赋值版本中讨论过?(&&=, ||=)。
回答by Jon Skeet
It's not a "shortcut" (or short-circuiting) operator in the way that || and && are (in that they won't evaluate the RHS if they already know the result based on the LHS) but it will do what you want in terms of working.
它不是 || 那样的“快捷方式”(或短路)运算符 和 && 是(因为如果他们已经知道基于 LHS 的结果,他们将不会评估 RHS)但它会在工作方面做你想要的。
As an example of the difference, this code will be fine if text
is null:
作为差异的一个例子,如果text
为空,这段代码就可以了:
boolean nullOrEmpty = text == null || text.equals("")
whereas this won't:
而这不会:
boolean nullOrEmpty = false;
nullOrEmpty |= text == null;
nullOrEmpty |= text.equals(""); // Throws exception if text is null
(Obviously you could do "".equals(text)
for that particular case - I'm just trying to demonstrate the principle.)
(显然你可以"".equals(text)
为那个特殊情况做- 我只是想证明这个原则。)
回答by Roman
List<Integer> params = Arrays.asList (defaultStock, defaultWholesale,
defaultRetail, defaultDelivery);
int minParam = Collections.min (params);
negativeValue = minParam < 0;
回答by Peter Lawrey
You could just have one statement. Expressed over multiple lines it reads almost exactly like your sample code, only less imperative:
你可以只有一个声明。用多行表示,它读起来几乎与您的示例代码完全一样,只是不那么必要:
boolean negativeValue
= defaultStock < 0
| defaultWholesale < 0
| defaultRetail < 0
| defaultDelivery < 0;
For simplest expressions, using |
can be faster than ||
because even though it avoids doing a comparison it means using a branch implicitly and that can be many times more expensive.
对于最简单的表达式, using|
可以比||
因为即使它避免进行比较也意味着隐式使用分支并且可能要贵很多倍。
回答by Carl
Though it might be overkill for your problem, the Guavalibrary has some nice syntax with Predicate
s and does short-circuit evaluation of or/and Predicate
s.
尽管对您的问题来说这可能有点矫枉过正,但Guava库对Predicate
s有一些很好的语法,并且可以对 or/and Predicate
s进行短路评估。
Essentially, the comparisons are turned into objects, packaged into a collection, and then iterated over. For or predicates, the first true hit returns from the iteration, and vice versa for and.
本质上,比较被转化为对象,打包成一个集合,然后迭代。对于 or 谓词,从迭代中返回第一个真命中,对于 and 反之亦然。
回答by oneklc
|| logical boolean OR
| bitwise OR
|| 逻辑布尔 OR
| 按位或
|= bitwise inclusive OR and assignment operator
|= 按位包含 OR 和赋值运算符
The reason why |= doesn't shortcircit is because it does a bitwise OR not a logical OR. That is to say:
|= 不短路的原因是因为它执行按位 OR 而不是逻辑 OR。也就是说:
C |= 2 is same as C = C | 2
回答by Krzysztof Jab?oński
If it is about readability I've got the concept of separation tested data from the testing logic. Code sample:
如果是关于可读性,我有将测试数据与测试逻辑分离的概念。代码示例:
// 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;
}
The code looks more verbose and self-explanatory. You may even create an array in method call, like this:
代码看起来更加冗长和不言自明。您甚至可以在方法调用中创建一个数组,如下所示:
checkIfAnyNegative(new DataType[] {
defaultStock,
defaultWholesale,
defaultRetail,
defaultDelivery
});
It's more readable than 'comparison string', and also has performance advantage of short-circuiting (at the cost of array allocation and method call).
它比“比较字符串”更具可读性,并且还具有短路的性能优势(以数组分配和方法调用为代价)。
Edit:Even more readability can be simply achieved by using varargs parameters:
编辑:通过使用 varargs 参数可以简单地实现更多的可读性:
Method signature would be:
方法签名将是:
boolean checkIfAnyNegative(DataType ... data)
And the call could look like this:
调用可能如下所示:
checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery );
回答by oxyt
It's an old post but in order to provide a different perspective for beginners, I would like give an example.
这是一篇旧帖子,但为了为初学者提供不同的视角,我想举一个例子。
I think the most common use case for a similar compound operator would be +=
. I'm sure we all wrote something like this:
我认为类似复合运算符的最常见用例是+=
. 我相信我们都写过这样的东西:
int a = 10; // a = 10
a += 5; // a = 15
What was the point of this? The point was to avoid boilerplate and eliminate the repetitive code.
这有什么意义?重点是避免样板文件并消除重复代码。
So, next line does exactly the same, avoiding to type the variable b1
twice in the same line.
因此,下一行完全相同,避免b1
在同一行中键入变量两次。
b1 |= b2;