web-dev-qa-db-ja.com

Java演算子:| =ビット単位ORそして例を割り当てる

誰かが書いたコードを調べたところ、|=使用法、Java演算子、ビット単位または代入演算を提案します。誰かが説明して例を教えてくれますか?

これを読み取るコードは次のとおりです。

    for (String search : textSearch.getValue())
         matches |= field.contains(search);
20
Rachel
_a |= b;
_

と同じです

_a = (a | b);
_

2つのオペランドのビットごとのORを計算し、割り当て結果を左側のオペランドに割り当てます。

サンプルコードを説明するには:

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

matchesbooleanだと思います。これは、ビット演算子が論理演算子と同じように動作することを意味します。

ループの各反復で、ORの現在の値をfield.contains()から返されたものとともにmatchesします。これには、すでにtrueの場合はtrueに設定し、field.contains()がtrueを返す場合はまたはに設定する効果があります。

したがって、ループ全体を通して、field.contains()への呼び出しのanytrueを返したかどうかを計算します。

29
Graham Borland

_a |= b_はa = (a | b)と同じです

ブール変数

booleanコンテキストでは、次のことを意味します。

_if (b) {
    a = true;
}
_

つまり、bがtrueの場合、aはtrueになります。それ以外の場合、aは変更されません。

ビット演算

ビット単位のコンテキストでは、bに設定されているすべてのバイナリビットがaに設定されることを意味します。 bでクリアされているビットは、aでは変更されません。

したがって、ビット0がbに設定されている場合、以下の例のように、それはaにも設定されます。

  • これにより、整数の最下位ビットがsetされます。

    _a |= 0x01_

  • これにより、下のビットがクリアされます:

    _a &= ~0x01_

  • これはトグル下のビットになります:

    _a ^= 0x01;_

10
Alnitak

このコード:

int i = 5;
i |= 10;

このコードと同等です:

int i = 5;
i = i | 10;

同様に、このコード:

boolean b = false;
b |= true;

これと同等です:

boolean b = false;
b = b | true;

最初の例では、ビット単位のORが実行されています。2番目の例では、ブール値ORが実行されています。

3
Óscar López

a |= ba = a | bと同じです

a | bは、両方のオペランドが整数型(int、shortなど)の場合、ビット演算子です。 両方のオペランドがブール値の場合、それはブール値またはです。

abの両方がブール値である場合、a | ba || bの違いは、最初に、両側が常に評価されることです。 、後でbは、aがfalseの場合にのみ評価されます。これは一種の「ショートカット」演算子です。

これは、次のような状況で役立ちます。

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がすでにtrueの場合、aは評価されません。

1
ɲeuroburɳ

コードにバグがあり、それが意図されていた可能性があります

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

少なくとも1つのフィールドにtrue変数が含まれている場合、一致はsearchになりますか?

1
adranale

そのコードスニペットは、その演算子をいつ使用するかについての悪い例です。正直なところ、この演算子をいつ使用するかについての良い例を考えることはできませんが、これが私の最善の試みです。

_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が必要です。そうしないと、2番目のifに対してsomethingIsTrue | testSomethingElseTrue()を実行できるからです。


最初の例で演算子を使用すべきではない理由がわからない場合は、次の理由があります。

パフォーマンスの観点からは、単なる比較ではなく、ループごとに比較と割り当てを行うため、不十分です。また、将来の反復が効果がない場合でも反復を継続します(matchestrueに設定されると、変更されず、_String.contains_には副作用がありません)。

この質問の存在だけに基づいて、読みやすさの観点からも貧弱です;)

したがって、そのスニペットの代わりに、次のようにします。

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

ちなみに、これを書いたとき、元のコーダーがビットを再生しすぎていたようです コードゴルフ :)

0
Briguy37