У меня есть длинный набор сравнений, чтобы сделать в Java, и я хотел бы знать, выходит ли один или несколько из них как верный. Строка сравнений была длинной и трудной читать, таким образом, я разбил ее для удобочитаемости и автоматически пошел для использования оператора ярлыка |=
вместо negativeValue = negativeValue || boolean
.
boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);
Я ожидаю negativeValue
чтобы быть верным, если какое-либо значение по умолчанию <что-то> оценивает, отрицательны. Действительно ли это допустимо? Это сделает то, что я ожидаю? Я не мог видеть, что это упомянуло на сайте или stackoverflow Sun, но Eclipse, кажется, не имеет проблему с ним и компиляции кода и выполнения.
Точно так же, если я хотел выполнить несколько логических пересечений, мог я использовать &=
вместо &&
?
|=
- это составной оператор присваивания (JLS 15.26.2) для логического оператора булевой логики |
(JLS 15.22.2); не путать с условным-или ||
(JLS 15.24). Существуют также &=
и ^=
, соответствующие составной версии присваивания булевых логических &
и ^
соответственно.
Другими словами, для булевых b1, b2
эти два оператора эквивалентны:
b1 |= b2;
b1 = b1 | b2;
Разница между логическими операторами (&
и |
) и их условными аналогами (&&
и ||
) в том, что первые не "замыкаются", а вторые замыкаются. То есть:
&
и |
всегда оценивают оба операнда&&
и ||
оценивают правый операндусловно; правый операнд оценивается только если его значение может повлиять на результат бинарной операции. Это означает, что правый операнд НЕ оценивается, если:
&&
оценивается в false
false
)||
оценивается в true
true
)Так что, возвращаясь к вашему первоначальному вопросу, да, эта конструкция действительна, и хотя |=
не совсем эквивалентное сокращение для =
и ||
, оно вычисляет то, что вы хотите. Поскольку правая часть оператора |=
в вашем случае является простой операцией сравнения целых чисел, тот факт, что |
не является сокращением, несущественен.
Есть случаи, когда замыкание желательно или даже необходимо, но ваш сценарий не из их числа.
К сожалению, в отличие от некоторых других языков, в Java нет &&=
и ||=
. Это обсуждалось в вопросе Почему в Java нет составных вариантов присваивания операторов условного-и и условного-или? (&&=, ||=).
У вас может быть только одно утверждение. Выраженный в нескольких строках, он читается почти так же, как ваш пример кода, только менее императивен:
boolean negativeValue
= defaultStock < 0
| defaultWholesale < 0
| defaultRetail < 0
| defaultDelivery < 0;
Для простейших выражений использование |
может быть быстрее, чем ||
, потому что даже если оно избегает выполнения сравнение означает неявное использование ветки, что может быть во много раз дороже.
List<Integer> params = Arrays.asList (defaultStock, defaultWholesale,
defaultRetail, defaultDelivery);
int minParam = Collections.min (params);
negativeValue = minParam < 0;
Это не оператор "быстрого доступа" (или короткого замыкания) в том смысле, в котором || и && (в том смысле, что они не будут оценивать RHS, если они уже знают результат на основе LHS), но он будет делать то, что вы хотите, с точки зрения работы .
В качестве примера разницы этот код подойдет, если text
имеет значение null:
boolean nullOrEmpty = text == null || text.equals("")
, тогда как это не будет:
boolean nullOrEmpty = false;
nullOrEmpty |= text == null;
nullOrEmpty |= text.equals(""); // Throws exception if text is null
(Очевидно, вы могли бы сделать "". Equals (текст)
для этого конкретного случая - я просто пытаюсь продемонстрировать принцип.)
Хотя это может быть излишним для вашей проблемы, библиотека Guava имеет хороший синтаксис с Predicate
s и выполняет оценку короткого замыкания или / и Predicate
] с.
По сути, сравнения превращаются в объекты, упаковываются в коллекцию, а затем повторяются. Для предикатов или первое истинное попадание возвращается с итерации, и наоборот для и.