私は通常、論理的にOR ||
をビット単位ではなく2つのブール値OR |
の間に使用する理由を疑問に思っています。
つまり、次を見てください:
if(true | true) // pass
if(true | false) // pass
if(false | true) // pass
if(false | false) // no pass
if(true || true) // pass
if(true || false) // pass
if(false || true) // pass
if(false || false) // no pass
|
の代わりに||
を使用できますか? &
と&&
でも同じです。
これらの演算子の||
および&&
形式ではなく、|
および&
形式を使用する場合、Javaは右側のオペランドのみを評価しません。
評価を短絡させたいかどうかは、-ほとんどの時間です。
短絡の利点を説明する良い方法は、次の例を検討することです。
Boolean b = true;
if(b || foo.timeConsumingCall())
{
//we entered without calling timeConsumingCall()
}
ジェレミーとピーターが述べたように、短絡のもう1つの利点は、null参照チェックです。
if(string != null && string.isEmpty())
{
//we check for string being null before calling isEmpty()
}
|
しない ブール式での短絡評価。 ||
は、最初のオペランドがtrueの場合、評価を停止しますが、|
は評価しません。
さらに、|
を使用して、byte/short/int/long値でビット単位のOR演算を実行できます。 ||
はできません。
そのため、例を挙げて他の回答に基づいて構築するために、以下の防御チェックでは短絡が非常に重要です。
if (foo == null || foo.isClosed()) {
return;
}
if (bar != null && bar.isBlue()) {
foo.doSomething();
}
代わりに|
と&
を使用すると、ここで NullPointerException
がスローされる可能性があります。
論理的な||
および&&
は、必要な場合にのみ右側をチェックします。 |
と&
は、常に両側をチェックします。
例えば:
int i = 12;
if (i == 10 & i < 9) // It will check if i == 10 and if i < 9
...
書き直してください:
int i = 12;
if (i == 10 && i < 9) // It will check if i == 10 and stop checking afterward because i != 10
...
もう一つの例:
int i = 12;
if (i == 12 | i > 10) // It will check if i == 12 and it will check if i > 10
...
書き直してください:
int i = 12;
if (i == 12 || i > 10) // It will check if i == 12, it does, so it stops checking and executes what is in the if statement
...
また、よくある落とし穴に注意してください。非遅延演算子は遅延演算子よりも優先されるため、次のようになります。
boolean a, b, c;
a || b && c; //resolves to a || (b && c)
a | b && c; //resolves to (a | b) && c
それらを混ぜるときは注意してください。
短絡に加えて、0または1以外の値でビット単位の論理演算を行うことは、条件付き論理とは非常に異なる意味を持つことに留意する必要があります。通常は|
と||
で同じですが、&
と&&
を使用すると、非常に異なる結果が得られます(たとえば、2 & 4
は0/falseで、2 && 4
は1/trueです)。
関数から取得しているものが実際にはエラーコードであり、0でないことをテストしている場合、これは非常に重要です。
これはJavaの問題ではなく、ブールに明示的に型キャストするか、0などと比較する必要がありますが、同様の構文(C/C++など)を持つ他の言語ではかなり紛らわしい。
また、&および|整数型の値にのみ適用でき、ブールテストに相当するすべてのものには適用できません。繰り返しますが、非Java言語では、暗黙的な!= 0
比較(ポインター、フロート、operator bool()
を持つオブジェクトなど)でブール値として使用できるものがかなり多くあり、それらのコンテキストではビット演算子はほとんど無意味です。
|
または&
の代わりに||
または&&
を使用するのは、非常に単純なブール式があり、ショートカット(つまりブランチ)のコストが後の式を評価しないことで節約できる時間よりも大きい場合だけです。
ただし、これは、最も低レベルのコードを除いてほとんど問題にならないマイクロ最適化です。
| b:any caseでbを評価します
|| b:bを評価しますifのみ aがfalseと評価されます
||は論理or演算子である|ビット単位のor演算子です。
boolean a = true;
boolean b = false;
if (a || b) {
}
int a = 0x0001;
a = a | 0x0002;
に加えて|ビット演算子です:||は短絡演算子です-1つの要素がfalseの場合、他の要素はチェックされません。
if(something || someotherthing)
if(something | someotherthing)
何かが真の場合、||何かを評価しませんが、しましょう。 if文の変数が実際に関数呼び出しである場合、||を使用しておそらく多くのパフォーマンスを節約できます。
演算子||
と&&
は条件演算子と呼ばれ、|
と&
はビット演算子と呼ばれます。それらは異なる目的に役立ちます。
条件演算子は、左側と右側の両方でboolean
に静的に評価される式でのみ機能します。
ビット演算子は、任意の数値オペランドで機能します。
論理比較を実行する場合は、条件演算子を使用する必要があります。これは、コードに何らかのタイプセーフを追加するためです。
| is the binary or operator
|| is the logic or operator
1)。(expression1 | expression2)、|演算子は、expression1の結果がtrueかfalseかに関係なく、expression2を評価します。
例:
class Or
{
public static void main(String[] args)
{
boolean b=true;
if (b | test());
}
static boolean test()
{
System.out.println("No short circuit!");
return false;
}
}
2)。(expression1 || expression2)、|| expression1がtrueの場合、演算子はexpression2を評価しません。
例:
class Or
{
public static void main(String[] args)
{
boolean b=true;
if (b || test())
{
System.out.println("short circuit!");
}
}
static boolean test()
{
System.out.println("No short circuit!");
return false;
}
}
サイドノート:Javaには| =がありますが|| =はありません
||を使用する必要がある場合の例最初の式が2番目の式が爆発するかどうかを確認するテストである場合です。例えば単一の|を使用する次の場合、NPEが発生する可能性があります。
public static boolean isNotSet(String text) {
return text == null || text.length() == 0;
}
この質問があったとき、これについてのアイデアを得るためにテストコードを作成しました。
public class HelloWorld{
public static boolean bool(){
System.out.println("Bool");
return true;
}
public static void main(String []args){
boolean a = true;
boolean b = false;
if(a||bool())
{
System.out.println("If condition executed");
}
else{
System.out.println("Else condition executed");
}
}
}
この場合、if条件の左側の値のみを変更し、aまたはbを追加します。
||
シナリオ、左側がtrueの場合[if(a || bool())]
出力"If condition executed"
||
シナリオ、左側がfalseの場合[if(b || bool())]
出力-
Bool
If condition executed
Conclusion of ||
||
を使用する場合、右側は左側がfalseの場合のみチェックします。
|
シナリオ、左側がtrueの場合[if(a | bool())]
出力-
Bool
If condition executed
|
シナリオ、左側がfalseの場合[if(b | bool())]
出力-
Bool
If condition executed
Conclusion of |
|
を使用する場合は、左側と右側の両方を確認してください。
それらの間の基本的な違いは最初に値をバイナリに変換してから、ビット単位のOR演算を実行します。一方、||データをバイナリに変換せず、元の状態でor式を実行するだけです。
int two = -2; int four = -4;
result = two | four; // bitwise OR example
System.out.println(Integer.toBinaryString(two));
System.out.println(Integer.toBinaryString(four));
System.out.println(Integer.toBinaryString(result));
Output:
11111111111111111111111111111110
11111111111111111111111111111100
11111111111111111111111111111110
詳細: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk
|| 2つの値の論理和をとってブール値を返します(そのため、LOGICALまたは
IE:
if (A || B)
AまたはBのいずれかがtrueの場合はtrueを返し、両方がfalseの場合はfalseを返します。
| 2つの値に対してビット演算を実行する演算子です。ビット単位の操作をよりよく理解するために、ここを読むことができます:
非短絡は有用です。 2つの式が評価されることを確認したい場合があります。たとえば、2つの個別のリストからオブジェクトを削除するメソッドがあるとします。このようなことをしたいと思うかもしれません:
class foo {
ArrayList<Bar> list1 = new ArrayList<Bar>();
ArrayList<Bar> list2 = new ArrayList<Bar>();
//Returns true if bar is removed from both lists, otherwise false.
boolean removeBar(Bar bar) {
return (list1.remove(bar) & list2.remove(bar));
}
}
メソッドが条件オペランドを代わりに使用した場合、最初のリストがfalseを返した場合、2番目のリストからオブジェクトを削除できません。
//Fails to execute the second remove if the first returns false.
boolean removeBar(Bar bar) {
return (list1.remove(bar) && list2.remove(bar));
}
それは驚くほど便利ではありませんし、(ほとんどのプログラミングタスクと同様に)他の手段でも実現できます。ただし、ビット単位のオペランドの使用例です。
||
ではなく|
を選択する理由を示唆する多くのユースケースがあります。いくつかのユースケースhave toすべての条件をチェックするために|
演算子を使用します。
たとえば、フォームの検証を確認し、ユーザーに表示する場合最初の無効なフィールドだけでなく、すべての無効なフィールドにエラーテキストが含まれる
||
演算子は、
if(checkIfEmpty(nameField) || checkIfEmpty(phoneField) || checkIfEmpty(emailField)) {
// invalid form with one or more empty fields
}
private boolean checkIfEmpty(Widget field) {
if(field.isEmpty()) {
field.setErrorMessage("Should not be empty!");
return true;
}
return false;
}
そのため、上記のスニペットでは、ユーザーがすべての空のフィールドを含むフォームを送信すると、エラーメッセージとともにnameField
のみが表示されます。しかし、それを変更すると、
if(checkIfEmpty(nameField) | checkIfEmpty(phoneField) | checkIfEmpty(emailField)) {
// invalid form with one or more empty fields
}
true
の状態に関係なく、各フィールドに適切なエラーメッセージが表示されます。
通常、プリインクリメント演算子とポストインクリメント演算子がある場合に使用します。次のコードを見てください:
package ocjpPractice;
/**
* @author tithik
*
*/
public class Ex1 {
public static void main(String[] args) {
int i=10;
int j=9;
int x=10;
int y=9;
if(i==10 | ++i>j){
System.out.println("it will print in first if");
System.out.println("i is: "+i);
}
if(x==10 ||++x>y){
System.out.println("it will print in second if");
System.out.println("x is: "+x);
}
}
}
出力:
最初に印刷されます
i:11
2秒後に印刷されます
xは:10
if
ブロックは両方とも同じですが、結果は異なります。 |
がある場合、両方の条件が評価されます。しかし、それが||
の場合、最初の条件がすでに真であるため、2番目の条件を評価しません。
| =ビット単位、または|| =ロジックまたは