22

我刚刚浏览了某人编写的代码,我看到了|=用法,查找 Java 运算符,它建议按位或分配操作,谁能解释并给我一个例子?

这是读取它的代码:

    for (String search : textSearch.getValue())
         matches |= field.contains(search);
4

6 回答 6

32
a |= b;

是相同的

a = (a | b);

它计算两个操作数的按位或并将结果分配给左操作数。

解释您的示例代码:

for (String search : textSearch.getValue())
    matches |= field.contains(search);

我认为matches是一个boolean;这意味着按位运算符的行为与逻辑运算符相同。

在循环的每次迭代中,它OR都是 的当前值,matches无论从field.contains(). 这具有将其设置为true是否已经为 truefield.contains()返回 true的效果。

因此,它会计算在整个循环中对 的任何调用是否已返回。field.contains()true

于 2012-04-13T13:50:02.233 回答
12

a |= b是相同的a = (a | b)

布尔变量

boolean上下文中,它意味着:

if (b) {
    a = true;
}

也就是说,如果b为真则为a真,否则a将不被修改。

位运算

在位明智的上下文中,这意味着设置 in 的每个二进制位都b将设置为a. 在 中清除的位b将在 中未修改a

因此,如果位 0 设置为b,它也将设置为a,如下例所示:

  • 这将设置整数的底部位:

    a |= 0x01

  • 这将清除底部位:

    a &= ~0x01

  • 这将切换底部位:

    a ^= 0x01;

于 2012-04-13T13:49:24.890 回答
3

这段代码:

int i = 5;
i |= 10;

相当于这段代码:

int i = 5;
i = i | 10;

同样,这段代码:

boolean b = false;
b |= true;

相当于这个:

boolean b = false;
b = b | true;

在第一个示例中,正在执行按位 OR。在第二个示例中,执行布尔 OR。

于 2012-04-13T13:50:45.467 回答
2

a |= b是相同的a = a | b

a | b如果两个操作数都是整数类型(int、short 等),则为位运算符。 如果两个操作数都是布尔值,那么它是一个布尔值或。

当两者都是布尔值时,a和之间的b区别在于,在第一个中,双方总是被评估,在后者中,只有当为假时才被评估。它是一种“快捷方式”运算符。a | ba || bba

这对于以下情况很有用:

if (a == null || a.equals(b)) { .. do something .. } // works

if (a == null | a.equals(b)) { .. do something .. } // NPE if a is null

另一方面,||实际上是作为字节码/机器码中的另一个条件跳转来实现的。在某些情况下,使用运算符评估布尔条件可能会更快,|以避免额外的跳转(以及因此分支预测等)。绝对是低级微基准测试来确定哪个更好(并且通常在大多数应用程序中并不重要)。

当你这样做时,a |= b你总是在评估ab。拥有运算符并没有真正意义a ||= b,因为等效项a = a || b将转换为:

if (a) a = true;
else if (b) a = true
else a = false;

...由于||评估的条件性质。换句话说,如果已经为真,b则不会被评估。a

于 2012-04-13T14:20:03.240 回答
1

代码有可能有错误吗?

matches = matches || field.contains(search);

true如果至少一个字段包含search变量,那么匹配应该是?

于 2012-04-13T13:55:09.993 回答
0

该代码片段是何时使用该运算符的一个糟糕示例。老实说,我想不出什么时候使用这个运算符的好例子,但这是我最好的尝试:

boolean somethingIsTrue = testSomethingTrue();
if(somethingIsTrue){
    //Do something
}
somethingIsTrue |= testSomethingElseTrue();
if(somethingIsTrue){
    //Do something else
}
somethingIsTrue |= testSomethingElseTrue2();
if(somethingIsTrue){
    //Do something else than something or something else
}   

注意: 您需要 3 个 if,否则您只能somethingIsTrue | testSomethingElseTrue()为第二个 if 做。


如果您想知道为什么不应该在第一个示例中使用运算符,原因如下:

从性能的角度来看,它很差,因为它对每个循环进行比较和分配,而不仅仅是比较。此外,即使未来的迭代没有效果,它也会继续迭代(一旦matches设置true它就不会改变,String.contains也没有副作用)。

从可读性的角度来看,它也很差,仅基于这个问题的存在;)

因此,代替那个片段我会去:

for (String search : textSearch.getValue()){
    if(field.contains(search)){
        matches = true;
        break;
    }
}

顺便说一句,在我看来,当他(s)写这篇文章时,原始编码器可能已经玩了太多代码高尔夫了:)

于 2012-04-13T16:36:01.023 回答