95

私は Java で長い間比較を行っていますが、そのうちの 1 つまたは複数が正しいかどうかを知りたいです。比較の文字列は長くて読みにくかったので、読みやすくするために分割し、自動的に|=ではなくショートカット演算子を使用するようになりましたnegativeValue = negativeValue || boolean

boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);

negativeValuedefault<something> 値のいずれかが負の場合は true になると思います。これは有効ですか?それは私が期待することをしますか?Sun のサイトや stackoverflow で言及されているのは見当たりませんでしたが、Eclipse には問題がないようで、コードはコンパイルおよび実行されます。


同様に、複数の論理積を実行したい場合、&=代わりに? を使用でき&&ますか?

4

8 に答える 8

215

これは、ブール論理演算子( JLS 15.22.2 )|=の複合代入演算子 ( JLS 15.26.2 ) です。conditional-or ( JLS 15.24 )と混同しないでください。また、ブール論理のandそれぞれの複合代入バージョンに対応するandもあります。|||&=^=&^

つまり、 の場合boolean b1, b2、これら 2 つは同等です。

 b1 |= b2;
 b1 = b1 | b2;

&論理演算子 (および|) と条件付きの対応する演算子 (&&および)の違いは||、前者が「短絡」しないことです。後者はそうします。あれは:

  • &そして| 常に両方のオペランドを評価します
  • &&||右オペランドを条件付きで評価します。右側のオペランドは、その値が二項演算の結果に影響を与える可能性がある場合にのみ評価されます。つまり、次の場合、右側のオペランドは評価されません。
    • の左オペランドは次のように&&評価されますfalse
      • (右のオペランドが何に評価されても、式全体が であるためfalse)
    • の左オペランドは次のように||評価されますtrue
      • (右のオペランドが何に評価されても、式全体が であるためtrue)

元の質問に戻ると、はい、その構成は有効であり、 whileはand|=の同等のショートカットではありませんが、必要なものを計算します。あなたの使用における演算子の右側は単純な整数比較演算であるため、短絡しないという事実は重要ではありません。=|||=|

短絡が必要な場合、または必要な場合もありますが、シナリオはその 1 つではありません。

&&=残念なことに、他のいくつかの言語とは異なり、Java には と がありません||=。これは、Java に条件付き AND および条件付き OR 演算子の複合代入バージョンがないのはなぜですか?という質問で説明されています。(&&=, ||=) .

于 2010-03-21T09:44:39.737 に答える
16

|| のような「ショートカット」(または短絡) 演算子ではありません。および && は (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)-私は原則を実証しようとしています。)

于 2010-03-21T09:12:10.893 に答える
3

1 つのステートメントのみを指定できます。複数の行で表現すると、サンプル コードとほぼ同じように読めますが、必須ではありません。

boolean negativeValue
    = defaultStock < 0 
    | defaultWholesale < 0
    | defaultRetail < 0
    | defaultDelivery < 0;

最も単純な式の場合、使用は比較を行うことを回避しますが、ブランチを暗黙的に使用することを意味し、何倍もコストがかかる可能性があるため、|より高速になる可能性があります。||

于 2010-03-21T10:14:14.600 に答える
1

あなたの問題にはやり過ぎかもしれませんが、Guavaライブラリには s を使用した優れた構文があり、 or/and s のPredicate短絡評価を行います。Predicate

基本的に、比較はオブジェクトに変換され、コレクションにパッケージ化されてから反復処理されます。or 述語の場合、反復から最初の真のヒットが返され、and の場合はその逆になります。

于 2010-03-22T14:28:50.810 に答える
1

読みやすさについては、テストロジックからテストデータを分離するという概念があります。コードサンプル:

// 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;
}

コードはより冗長で、一目瞭然です。次のように、メソッド呼び出しで配列を作成することもできます。

checkIfAnyNegative(new DataType[] {
    defaultStock,
    defaultWholesale,
    defaultRetail,
    defaultDelivery
});

これは「比較文字列」よりも読みやすく、ショートサーキットのパフォーマンス上の利点もあります (配列の割り当てとメソッド呼び出しを犠牲にして)。

編集: varargs パラメータを使用することで、さらに読みやすくすることができます。

メソッドの署名は次のようになります。

boolean checkIfAnyNegative(DataType ... data)

呼び出しは次のようになります。

checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery );
于 2013-04-25T09:38:56.057 に答える
0

|| 論理ブール OR
| ビットごとの OR

|= ビットごとの包含 OR および代入演算子

|= が短絡しない理由は、論理 OR ではなくビットごとの OR を行うためです。つまり、次のようになります。

C |= 2 は C = C | と同じです。2

Java オペレーターのチュートリアル

于 2013-01-11T19:15:04.937 に答える
0
List<Integer> params = Arrays.asList (defaultStock, defaultWholesale, 
                                       defaultRetail, defaultDelivery);
int minParam = Collections.min (params);
negativeValue = minParam < 0;
于 2010-03-21T09:15:38.240 に答える