Java에서 수행 할 긴 비교 세트가 있으며 그중 하나 이상이 사실로 나오는지 알고 싶습니다. 비교 문자열이 길고 읽기 어려웠 기 때문에 가독성을 위해 분리했고 자동으로 . |=
대신 단축키 연산자를 사용했습니다 negativeValue = negativeValue || boolean
.
boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);
negativeValue
default <something> 값이 음수이면 true가 될 것으로 예상 합니다. 이것이 유효합니까? 내가 기대하는대로 작동할까요? Sun의 사이트 또는 stackoverflow에서 언급 된 것을 볼 수 없었지만 Eclipse에는 문제가없는 것 같고 코드가 컴파일되고 실행됩니다.
마찬가지로 여러 논리적 교차를 수행하려면 &=
대신 &&
?를 사용할 수 있습니다 .
답변
는 |=
복합 할당 연산자이다 ( JLS 15.26.2 부울 논리 연산자) |
( JLS 15.22.2 ); conditional-or ||
( JLS 15.24 ) 와 혼동하지 마십시오 . 또한 거기 &=
와 ^=
논리적 부울의 화합물 할당 버전에 대응 &
하고 ^
, 각각.
즉,의 boolean b1, b2
경우이 두 가지는 동일합니다.
b1 |= b2;
b1 = b1 | b2;
논리 연산자의 차이 ( &
및 |
그 조건 대응 (비교) &&
과는 ||
) 전자는 “단락”을하지 않는 것입니다; 후자는합니다. 그건:
&
그리고|
항상 두 피연산자를 평가&&
그리고||
우측 피연산자를 평가 조건부 ; 오른쪽 피연산자는 해당 값이 이진 연산의 결과에 영향을 미칠 수있는 경우에만 평가됩니다. 즉, 다음과 같은 경우 오른쪽 피연산자가 평가되지 않습니다.- 의 왼쪽 피연산자는 다음과 같이
&&
평가됩니다.false
- (오른쪽 피연산자가 무엇으로 평가 되든 전체 표현식이이므로
false
)
- (오른쪽 피연산자가 무엇으로 평가 되든 전체 표현식이이므로
- 의 왼쪽 피연산자는 다음과 같이
||
평가됩니다.true
- (오른쪽 피연산자가 무엇으로 평가 되든 전체 표현식이이므로
true
)
- (오른쪽 피연산자가 무엇으로 평가 되든 전체 표현식이이므로
- 의 왼쪽 피연산자는 다음과 같이
그래서 원래의 질문으로 돌아가서, 예, 그 구조는 유효하며 |=
는 =
및 ||
에 대한 바로 가기는 아니지만 원하는 것을 계산합니다. |=
사용 하는 연산자 의 오른쪽 은 간단한 정수 비교 연산이므로 |
단락되지 않는 사실 은 중요하지 않습니다.
단락이 필요하거나 필요한 경우가 있지만 시나리오는 그중 하나가 아닙니다.
다른 언어와 달리 Java에는 &&=
및 ||=
. 이것은 왜 Java에 conditional-and and conditional-or 연산자의 복합 할당 버전이 없습니까? 라는 질문에서 논의되었습니다 . (&& =, || =) .
답변
그런 식으로 “단축”(또는 단락) 연산자가 아닙니다 || &&는 (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)
그 특정한 경우에 대해 할 수 있습니다 -나는 단지 원리를 보여주기위한 것입니다.)
답변
당신은 단지 하나의 진술을 가질 수 있습니다. 여러 줄로 표현하면 샘플 코드와 거의 똑같이 읽습니다.
boolean negativeValue
= defaultStock < 0
| defaultWholesale < 0
| defaultRetail < 0
| defaultDelivery < 0;
가장 간단한 표현식의 경우 using 이 비교를 피하더라도 암시 적으로 분기를 사용하는 것을 의미하며 훨씬 더 많은 비용이들 수 있기 때문에 사용 |
이 더 빠를 ||
수 있습니다.
답변
그것은 당신의 문제에 과잉 일 수 있지만, Guava 라이브러리는 Predicate
s와 함께 멋진 구문을 가지고 있으며 or / and Predicate
s에 대한 단락 평가를 수행 합니다.
기본적으로 비교는 객체로 변환되고 컬렉션으로 패키징 된 다음 반복됩니다. 또는 술어의 경우 첫 번째 실제 적중이 반복에서 리턴되고 and의 경우 그 반대의 경우도 마찬가지입니다.
답변
가독성에 관한 경우 테스트 논리에서 테스트 데이터를 분리한다는 개념이 있습니다. 코드 샘플 :
// 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 );
답변
오래된 게시물이지만 초보자에게 다른 관점을 제공하기 위해 예를 들어보고 싶습니다.
비슷한 복합 연산자의 가장 일반적인 사용 사례는 +=
. 나는 우리 모두가 다음과 같이 썼다고 확신합니다.
int a = 10; // a = 10
a += 5; // a = 15
이것의 요점은 무엇입니까? 요점은 상용구를 피하고 반복적 인 코드를 제거하는 것이 었습니다.
따라서 다음 줄은 b1
동일한 줄에 변수를 두 번 입력하는 것을 피하면서 정확히 동일합니다.
b1 |= b2;
답변
List<Integer> params = Arrays.asList (defaultStock, defaultWholesale,
defaultRetail, defaultDelivery);
int minParam = Collections.min (params);
negativeValue = minParam < 0;