web-dev-qa-db-ja.com

ブール演算子の違い:&vs && and | vs ||

&&||のルールは知っていますが、&|とは何ですか?これらを例で説明してください。

99
Sumithra

これらはビット単位のANDおよびビット単位のOR演算子です。

int a = 6; // 110
int b = 4; // 100

// Bitwise AND    

int c = a & b;
//   110
// & 100
// -----
//   100

// Bitwise OR

int d = a | b;
//   110
// | 100
// -----
//   110

System.out.println(c); // 4
System.out.println(d); // 6

Java言語仕様( 15.22.115.22.2 )の演算子のさまざまな動作に関する適切なセクションを指摘してくれたCarlosに感謝します。その入力に基づいています。

実際、両方の入力がブールである場合、演算子はブール論理演算子と見なされ、条件付きAND(&&)および条件付きOR(||)演算子と同様に動作します。 tは短絡しているため、次のことが安全です。

if((a != null) && (a.something == 3)){
}

これではありません:

if((a != null) & (a.something == 3)){
}

「短絡」とは、オペレーターが必ずしもすべての条件を調べるわけではないことを意味します。上記の例では、&&anullでない場合にのみ2番目の条件を検査します(そうでない場合はステートメント全体がfalseを返し、とにかく以下の条件を検査する必要があります)したがって、a.somethingのステートメントは例外を発生させないか、「安全」と見なされます。

&演算子は常に句内のすべての条件を検査するため、上記の例では、aが実際にnull値であるときにa.somethingが評価され、例外が発生します。

122
Justin Niessner

私はあなたが両方の演算子の論理的な意味について話していると思います、ここであなたはテーブルの再開を持っています:

boolean a, b;

Operation     Meaning                       Note
---------     -------                       ----
   a && b     logical AND                    short-circuiting
   a || b     logical OR                     short-circuiting
   a &  b     boolean logical AND            not short-circuiting
   a |  b     boolean logical OR             not short-circuiting
   a ^  b     boolean logical exclusive OR
  !a          logical NOT

short-circuiting        (x != 0) && (1/x > 1)   SAFE
not short-circuiting    (x != 0) &  (1/x > 1)   NOT SAFE
101
Torres

ここにはたくさんの答えがありますが、それらはすべて少し混乱しているように見えます。したがって、Java Oracleスタディガイドからいくつかの調査を行った後、&&または&を使用する3つの異なるシナリオを思いつきました。 3つのシナリオは、論理ANDビットごとのAND、およびブールANDです。

論理AND:論理AND(条件付きAND)は&&演算子を使用します。ショートサーキットの意味です。左のオペランドが偽の場合、右のオペランドは評価されません。
例:

int x = 0;
if (false && (1 == ++x) {
    System.out.println("Inside of if");
}
System.out.println(x); // "0"

上記の例では、ifステートメントの最初のオペランドがfalseであるため、xのコンソールに出力される値は0になります。したがって、Javaは(1 == ++ x)を計算する必要がないため、x計算されません。

ビット単位のAND:ビット単位のANDは演算子を使用します。値に対してビット演算を実行するために使用されます。 exの2進数の演算を見ると、何が起こっているのかを簡単に確認できます。

int a = 5;     //                    5 in binary is 0101
int b = 12;    //                   12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4

例でわかるように、数字5と12のバイナリ表現が並んでいる場合、ビットごとのANDを実行すると、両方の数字の同じ数字が1であるバイナリ番号のみが生成されます。したがって、0101&1100 == 0100。10進数で5と12 == 4です。

ブールAND:ブールAND演算子は、ビット単位のANDと論理ANDの両方と同様に異なる動作をします。私は、2つのブール値(またはビット)の間でビット単位のANDを実行するものと考えたいので、演算子を使用します。ブール値は論理式の結果でもあります。

論理ANDと同様に、trueまたはfalseの値を返しますが、論理ANDとは異なり、短絡しません。その理由は、ビット単位のANDを実行するために、左右の両方のオペランドの値を知る必要があるためです。例は次のとおりです。

int x = 0;
if (false & (1 == ++x) {
    System.out.println("Inside of if");
}
System.out.println(x); //"1"

ステートメントが実行されると、左オペランドがfalseであっても式(1 == ++ x)が実行されます。したがって、xに対して出力される値は、増分されるため1になります。

これは、論理OR(||)、ビット単位OR(|)、およびブールOR(|)にも当てはまります。これで混乱が解消されることを願っています。

24

演算子&&および||ショートサーキットです。つまり、左辺の式の値が結果を決定するのに十分な場合、右辺の式を評価しません。

7

&および| &&および||と同じ結果を提供します演算子。違いは、式の両側を常に評価することです。最初の条件が結果を決定するのに十分である場合、評価を停止します。

5
Brian Scott

Javaでは、単一の演算子&、|、^ 、!オペランドに依存します。両方のオペランドが整数の場合、ビット単位の演算が実行されます。両方がブール値である場合、「論理」操作が実行されます。

両方のオペランドが一致しない場合、コンパイル時エラーがスローされます。

二重演算子&&、||単一の対応するものと同様に動作しますが、両方のオペランドは条件式でなければなりません、例えば:

if((a <0)&&(b <0)){...}または同様に、if((a <0)||(b <0)){...}

ソース:Java programming lang 4th ed

2
aaron p.

&&; ||論理演算子です...

&; |ブール論理演算子です。..非短絡

式の実行の違いに移行します。ビット演算子は、左辺の結果に関係なく両側を評価します。ただし、論理演算子を使用して式を評価する場合、右辺の式の評価は左辺の条件に依存します。

例えば:

int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
    System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

これはi = 26を出力します。 j = 25、最初の条件が偽であるため、右側の条件に関係なく結果が偽であるため、右側の条件はバイパスされます。(短絡)

int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
    System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

しかし、これはi = 26を出力します。 j = 26、

1
Nickhil

&および|は、整数型のビットごとの演算子です(例:int): http://download.Oracle.com/javase/tutorial/Java/nutsandbolts/op3。 html

&&および||はブール値のみで動作します(他の回答がすでに述べているように、短絡します)。

1
Bruno

ビットごとのANDおよびビットごとのOR演算子は、同じ式で使用される条件付きANDおよび条件付きORの前に常に評価されることを知っておくと役立つ場合があります。

if ( (1>2) && (2>1) | true) // false!
1
alexmeia

基本的な違いは、&が主にlongint、またはbyteのビットごとの演算に使用され、マスクの種類に使用できることですが、結果は異なる場合があります論理&&の代わりに使用しても。

違いはいくつかのシナリオでより顕著です:

  1. いくつかの式の評価には時間がかかります
  2. 式の1つの評価は、前の式が真である場合にのみ実行できます
  3. 式にはいくつかの副作用があります(意図的かどうか)

最初のポイントは非常に簡単で、バグは発生しませんが、より時間がかかります。 1つの条件ステートメントに複数の異なるチェックがある場合は、より安価であるか、失敗する可能性が高いチェックを左側に配置します。

2番目のポイントについては、次の例を参照してください。

if ((a != null) & (a.isEmpty()))

2番目の式を評価するとnullが生成されるため、これはNullPointerExceptionに対して失敗します。論理演算子&&はレイジーです。左のオペランドがfalseの場合、右のオペランドが何であっても結果はfalseです。

3番目のポイントの例-トリガーやカスケードなしでDBを使用するアプリがあるとします。 Buildingオブジェクトを削除する前に、Departmentオブジェクトの建物を別の建物に変更する必要があります。また、操作ステータスがブール値として返されるとしましょう(true =成功)。次に:

if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))

これは両方の式を評価するため、何らかの理由で部門の更新が失敗した場合でも、建物の削除を実行します。 &&を使用すると、意図したとおりに機能し、最初の障害の後に停止します。

a || bについては、!(!a && !b)と同等です。aがtrueの場合は停止し、これ以上の説明は不要です。

0
Vlasec

ブール値演算子を含む式が評価される場合、両方のオペランドが評価されます。次に、&演算子がオペランドに適用されます。

&&演算子を含む式が評価されると、最初のオペランドが評価されます。第1オペランドの評価がfalseの場合、第2オペランドの評価はスキップされます。

最初のオペランドがtrueの値を返す場合、2番目のオペランドが評価されます。 2番目のオペランドがtrueの値を返す場合、&&演算子が1番目と2番目のオペランドに適用されます。

同様の|および||。

0