Programing

왜 일반적으로`|`가 아닌`||`를 사용합니까? 차이점은 무엇입니까?

lottogame 2020. 4. 27. 07:55
반응형

왜 일반적으로`|`가 아닌`||`를 사용합니까? 차이점은 무엇입니까?


||두 비트가 아닌 두 부울 사이에 논리 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

|대신에 사용할 수 있습니까 ||? 와 같은 것은 &하고 &&.


이 연산자 and 형식 대신 ||and &&형식 을 사용하면 Java는 오른쪽 피연산자 만 평가하지 않아도됩니다.|&

대부분 의 경우 평가를 단락하려는 경우 문제가됩니다 .

단락의 이점을 설명하는 좋은 방법은 다음 예를 고려하는 것입니다.

Boolean b = true;
if(b || foo.timeConsumingCall())
{
   //we entered without calling timeConsumingCall()
}

제레미와 피터가 언급했듯이 단락에 대한 또 다른 이점은 null 참조 검사입니다.

if(string != null && string.isEmpty())
{
    //we check for string being null before calling isEmpty()
}

더 많은 정보


| 부울 식에서 단락 평가를 수행하지 않습니다 . ||첫 번째 피연산자가 참인지 평가를 중단하지만 |그렇지 않습니다.

또한 |byte / short / int / long 값에 대해 비트 단위 OR 연산을 수행하는 데 사용할 수 있습니다. ||할 수 없습니다.


따라서 예를 들어 다른 답변을 작성하려면 다음 방어 검사에서 단락이 중요합니다.

if (foo == null || foo.isClosed()) {
    return;
}

if (bar != null && bar.isBlue()) {
    foo.doSomething();
}

사용 |&A의 초래할 수 대신 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 & 40 / 거짓 동안은 2 && 41 / 사실이다).

함수에서 얻는 것이 실제로 오류 코드이고 0이 아닌지를 테스트하는 경우 이것은 매우 중요합니다.

Java에서 부울 또는 0 등과 비교하기 위해 명시 적으로 타입 캐스트 해야하는 문제는 아니지만 비슷한 구문 (C / C ++ 등)이있는 다른 언어에서는 상당히 혼란 스러울 수 있습니다.

또한 & 및 | 부울 테스트와 동등한 모든 것이 아니라 정수 유형 값에만 적용 할 수 있습니다. 다시 말하지만, Java 이외의 언어에서는 암시 적 != 0비교 (포인터, 플로트, 객체 operator bool()등)를 사용하여 부울로 사용할 수있는 몇 가지 사항이 있으며 비트 연산자는 이러한 문맥에서 거의 무의미합니다.


당신이 사용하는 것이 유일한 시간 |또는 &대신에 ||또는 &&당신은 매우 간단한 불리언 표현식과 짧은 절단 (즉, 지점)의 비용이있을 때이다가 나중에 표현식을 평가하지 선방 시간 당신보다 더 크다.

그러나 이것은 가장 낮은 수준의 코드를 제외하고는 거의 중요하지 않은 미세 최적화입니다.


|| 논리 또는 연산자입니다 | 비트 또는 연산자입니다.

boolean a = true;
boolean b = false;

if (a || b) {
}

int a = 0x0001;
a = a | 0x0002;

| b : 어떤 경우 에도 b를 평가

|| b : a 가 false로 평가 된 경우에만 b를 평가합니다.


사실에 더하여 | 비트 연산자입니다. || 단락 연산자입니다. 한 요소가 거짓이면 다른 요소를 검사하지 않습니다.

 if(something || someotherthing)
 if(something | someotherthing)

무언가가 참이면 || 동안 다른 것을 평가하지 않습니다 | 할 것이다. if 문의 변수가 실제로 함수 호출 인 경우 || 아마도 많은 성능을 절약하고 있습니다.


| is the binary or operator

|| is the logic or operator

연산자 ||&&호출 조건 연산자를 , 동안 |&호출 사업자와 비트 단위로 . 그들은 다른 목적으로 사용됩니다.

조건부 연산자는 boolean왼쪽과 오른쪽 모두에서 정적으로 평가되는 표현식에서만 작동합니다 .

비트 연산자는 모든 숫자 피연산자와 함께 작동합니다.

논리적 비교를 수행하려면 조건 연산자 를 사용해야 합니다. 코드에 일종의 유형 안전을 추가하기 때문입니다.


참고 : Java에는 | =가 있지만 || =는 없습니다.

||를 사용해야하는 경우의 예 첫 번째 표현식이 두 번째 표현식이 터지는 지 확인하기위한 테스트 일 때입니다. 예를 들어 단일 | 따라서 다음과 같은 경우 NPE가 발생할 수 있습니다.

public static boolean isNotSet(String text) {
   return text == null || text.length() == 0;
}

다른 답변은 연산자 간의 기능적 차이를 다루는 데 도움이되었지만 오늘날 존재하는 거의 모든 C 파생 언어에 적용 할 수 있습니다. 질문에는 태그가 지정되어 있으므로 Java 언어에 대해 구체적이고 기술적으로 답변하려고 노력할 것입니다.

&|정수 비트 연산자 또는 부울 논리 연산자 중 하나가 될 수 있습니다. 비트 및 논리 연산자 ( §15.22 ) 의 구문은 다음과 같습니다.

AndExpression:
  EqualityExpression 
  AndExpression & EqualityExpression

ExclusiveOrExpression:
  AndExpression 
  ExclusiveOrExpression ^ AndExpression

InclusiveOrExpression:
  ExclusiveOrExpression 
  InclusiveOrExpression | ExclusiveOrExpression

위한 구문 EqualityExpression으로 정의 §15.21 필요 RelationalExpression에 정의 §15.20 차례로 요구 ShiftExpression하고 ReferenceType정의 §15.19§4.3 각각. ShiftExpression필요 AdditiveExpression에 정의 §15.18 기본 등 산술, 단항 연산자, 정의, 드릴 다운을 계속하는 ReferenceType유형을 대표하는 모든 다양한 방법으로 드릴 다운합니다. (반면 ReferenceType프리미티브 타입을 포함하지 않는가 배열을위한 측정 유형 수있는 바와 같이, 기본 형태의 정의는 궁극적으로 필요 하다ReferenceType ).

비트 연산자와 논리 연산자에는 다음과 같은 속성이 있습니다.

  • 이 연산자는 우선 순위 &가 가장 높고 우선 순위 |가 가장 낮은 다른 우선 순위를 갖습니다.
  • 이러한 각 연산자는 구문 적으로 왼쪽 연관되어 있습니다 (각 그룹은 왼쪽에서 오른쪽으로).
  • 피연산자 표현식에 부작용이없는 경우 각 연산자는 정식입니다.
  • 각 연산자는 연관되어 있습니다.
  • 비트 및 논리 연산자를 사용하여 숫자 유형의 두 피연산자 또는 유형의 두 피연산자를 비교할 수 있습니다 boolean. 다른 모든 경우에는 컴파일 타임 오류가 발생합니다.

연산자가 비트 연산자인지 논리 연산자인지의 구분은 피연산자가 "기본 정수 유형으로 변환 가능"하는지 ( §4.2 ) 또는 유형 boolean인지 또는 Boolean( §5.1.8 ) 인지에 따라 다릅니다 .

피연산자가 정수 유형 인 경우 두 피연산자 모두에 대해 이진 숫자 승격 ( §5.6.2 )이 수행되어 연산에 대해 longs 또는 ints 로 남겨 집니다. 연산 유형은 (승격 된) 피연산자의 유형입니다. 이 시점에서 &비트 AND ^가되고 비트 배타적 OR |이되고 비트 비트가 OR이됩니다. ( §15.22.1 )

피연산자가 boolean또는 Boolean경우, 피연산자는 필요한 경우 개봉 변환을 수행하고 ( §5.1.8 ), 작업 유형은입니다 boolean. &초래할 것이다 true두 피연산자가 있다면 true, ^발생할 것이다 true피연산자가 모두 다른 경우 및 |발생합니다 true피연산자 경우 true. ( §15.22.2 )

반대로 && "조건부 및 연산자"( §15.23 )이고 ||"조건부 또는 연산자"( §15.24 )입니다. 그들의 구문은 다음과 같이 정의됩니다.

ConditionalAndExpression:
  InclusiveOrExpression 
  ConditionalAndExpression && InclusiveOrExpression

ConditionalOrExpression:
  ConditionalAndExpression 
  ConditionalOrExpression || ConditionalAndExpression

&&&왼쪽 피연산자가이면 오른쪽 피연산자 만 평가한다는 점을 제외하고 는 같습니다 true. 왼쪽 피연산자가이면 오른쪽 피연산자 만 평가한다는 점을 제외하고 ||는 같습니다 .|false

조건부 및 속성은 다음과 같습니다.

  • 조건부 및 연산자는 구문 적으로 왼쪽 연관입니다 (왼쪽에서 오른쪽으로 그룹화 됨).
  • 조건부 및 연산자는 부작용 및 결과 값과 관련하여 완전히 연관됩니다. 즉, 임의의 표현을 위해 a, b그리고 c, 식의 평가는 ((a) && (b)) && (c)동일한 부작용 발현의 평가로서, 동일한 순서로 발생하여, 동일한 결과를 생성한다 (a) && ((b) && (c)).
  • 조건부 및 연산자의 각 피연산자는 유형 boolean또는 이어야합니다. 그렇지 않으면 Boolean컴파일 타임 오류가 발생합니다.
  • 조건부 및 표현식의 유형은 항상 boolean입니다.
  • 런타임시 왼쪽 피연산자 표현식이 먼저 평가됩니다. 결과에 유형이 있으면 개봉Boolean 변환 ( §5.1.8 ) 이 적용됩니다 .
  • 결과 값이 false인 경우 조건부 및 표현식의 값은 false이고 오른쪽 피연산자 표현식은 평가되지 않습니다.
  • 왼쪽 피연산자의 값이 인 경우 true오른쪽 표현식이 평가됩니다. 결과에 유형이 있으면 개봉Boolean 변환 ( §5.1.8 ) 이 적용됩니다 . 결과 값은 조건부 및 표현식의 값이됩니다.
  • 따라서, &&동일한 결과 계산 &boolean피연산자. 오른쪽 피연산자 표현식이 항상이 아니라 조건부로 평가된다는 점만 다릅니다.

조건부 또는 속성은 다음과 같습니다.

  • 조건부 또는 연산자는 구문 적으로 왼쪽 연관입니다 (왼쪽에서 오른쪽으로 그룹화 됨).
  • 조건부 또는 연산자는 부작용 및 결과 값과 관련하여 완전히 연관되어 있습니다. 즉, 임의의 표현을 위해 a, b그리고 c, 식의 평가는 ((a) || (b)) || (c)동일한 부작용 발현의 평가로서, 동일한 순서로 발생하여, 동일한 결과를 생성한다 (a) || ((b) || (c)).
  • 조건부 또는 연산자의 각 피연산자 유형은 boolean또는 이어야합니다. 그렇지 않으면 Boolean컴파일 타임 오류가 발생합니다.
  • 조건부 또는 표현식의 유형은 항상 boolean입니다.
  • 런타임시 왼쪽 피연산자 표현식이 먼저 평가됩니다. 결과에 유형이 있으면 개봉Boolean 변환 ( §5.1.8 ) 이 적용됩니다 .
  • 결과 값이 true인 경우 조건부 또는 표현식의 값은 true이고 오른쪽 피연산자 표현식은 평가되지 않습니다.
  • 왼쪽 피연산자의 값이 인 경우 false오른쪽 표현식이 평가됩니다. 결과에 유형이 있으면 개봉Boolean 변환 ( §5.1.8 ) 이 적용됩니다 . 결과 값은 조건부 또는 표현식의 값이됩니다.
  • 따라서 on 또는 피연산자 ||와 동일한 결과를 계산합니다 . 오른쪽 피연산자 표현식이 항상이 아니라 조건부로 평가된다는 점만 다릅니다.|booleanBoolean

즉, 같은 @JohnMeagher 반복적으로 의견 지적했다 &|사실이 아닌 짧은 단락 중 하나 인 피연산자의 특정 케이스에 부울 연산자를, 있습니다 boolean또는 Boolean. 모범 사례 (예 : 보조 효과 없음)를 사용하면 약간의 차이가 있습니다. 그러나 피연산자가 booleans 또는 Booleans 가 아닌 경우 연산자는 매우 다르게 동작합니다 . 비트 및 논리 연산은 단순히 높은 수준의 Java 프로그래밍에서 잘 비교되지 않습니다.


1). (식 1 | 식 2), | 연산자는 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). (식 1 || 식 2), || 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;
    }
}

|| 두 개의 값을 OR하여 부울 값을 반환합니다. (논리적 또는

IE :

if (A || B) 

A 또는 B가 true이면 true를 반환하고 둘 다 false이면 false를 반환합니다.

| 두 값에 대해 비트 단위 연산을 수행하는 연산자입니다. 비트 단위 연산을 더 잘 이해하려면 다음을 읽으십시오.

http://en.wikipedia.org/wiki/Bitwise_operation


한 가지 주요 차이점은 || &&는 "단락"을 나타내므로 RHS는 필요한 경우에만 평가됩니다.

예를 들어

if (a || b) {
    path1...
} else {
    path2..
}

위의 a가 true이면 b가 테스트되지 않고 path1이 실행됩니다. 경우 | 'a'가 참이더라도 양쪽을 평가합니다.

좀 더 자세한 정보는 여기여기를 참조하십시오 .

도움이 되었기를 바랍니다.


비 단락이 유용 할 수 있습니다. 때로는 두 표현식이 평가되도록하려고합니다. 예를 들어, 두 개의 개별 목록에서 객체를 제거하는 메소드가 있다고 가정하십시오. 다음과 같은 작업을 수행 할 수 있습니다.

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를 리턴하면 두 번째 목록에서 오브젝트를 제거하지 못합니다.

//Fails to execute the second remove if the first returns false.
boolean removeBar(Bar bar) {
    return (list1.remove(bar) && list2.remove(bar));
}

놀랍게도 유용하지 않으며 (대부분의 프로그래밍 작업과 마찬가지로) 다른 방법으로 달성 할 수 있습니다. 그러나 비트 피연산자의 사용 사례입니다.


그들 사이의 기본적인 차이점은 | 먼저 값을 이진수로 변환 한 다음 비트 단위 또는 연산을 수행합니다. 한편, || 데이터를 이진으로 변환하지 않고 원래 상태에서 또는 식을 수행합니다.

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


이 질문을 받았을 때 이에 대한 아이디어를 얻기 위해 테스트 코드를 만들었습니다.

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");
     }

 }
}

이 경우 a 또는 b를 추가하는 if 조건의 왼쪽 값만 변경합니다.

|| 시나리오가 왼쪽 인 경우 [if (a || bool ())]

산출 "If condition executed"

|| 시나리오가 왼쪽 인 경우 [if (b || bool ())]

산출-

Bool
If condition executed

Conclusion of || 를 사용할 때 ||오른쪽은 왼쪽이 거짓 일 때만 확인합니다.

| 시나리오가 왼쪽 인 경우 [if (a | bool ())]

산출-

Bool
If condition executed

| 시나리오가 왼쪽 인 경우 [if (b | bool ())]

산출-

Bool
If condition executed

Conclusion of | When use |, check both left and right side.


| = bitwise or, || = logic or


usually I use when there is pre increment and post increment operator. Look at the following code:

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

output:

it will print in first if
i is: 11

it will print in second if
x is: 10

both if blocks are same but result is different. when there is |, both the conditions will be evaluated. But if it is ||, it will not evaluate second condition as the first condition is already true.


There are many use cases suggesting why should you go for || rather than | . Some use cases have to use | operator to check all the conditions.

For example, if you want to check form validation and you want to show the user all the invalid fields with error texts rather than just a first invalid field.

|| operator would be,

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

So with above snippet, if user submits the form with ALL empty fields, ONLY nameField would be shown with error message. But, if you change it to,

   if(checkIfEmpty(nameField) | checkIfEmpty(phoneField) | checkIfEmpty(emailField)) {
      // invalid form with one or more empty fields
   }

It will show proper error message on the each field irrespective of true conditions.


After carefully reading this topic is still unclear to me if using | as a logical operator is conform to Java pattern practices.

I recently modified code in a pull request addressing a comment where

if(function1() | function2()){
  ...
}

had to be changed to

boolean isChanged = function1();
isChanged |= function2();
if (isChanged){
  ...
}

What is the actual accepted version?

Java documentation is not mentioning | as a logical non-shortcircuiting OR operator.

Not interested in a vote but more in finding out the standard?! Both code versions are compiling and working as expected.


|| is a logical or and | is a bit-wise or.


Java operators

| is bitwise or, || is logical or.


Take a look at:

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html

| is bitwise inclusive OR

|| is logical OR


| is a bitwise operator. || is a logical operator.

One will take two bits and or them.

One will determine truth (this OR that) If this is true or that is true, then the answer is true.

Oh, and dang people answer these questions fast.

참고URL : https://stackoverflow.com/questions/7101992/why-do-we-usually-use-not-what-is-the-difference

반응형