Операторы Java: | = побитовое ИЛИ и назначить пример
Я просто просматриваю код, который написал кто-то, и я видел использование |=
, глядя на Java-операторы, он предлагает поразрядные операции и назначает операцию, может ли кто-нибудь объяснить и дать мне пример?
Вот код, который его читал:
for (String search : textSearch.getValue())
matches |= field.contains(search);
Ответы
Ответ 1
a |= b;
совпадает с
a = (a | b);
Он вычисляет побитовый OR двух операндов, а присваивает результат левому операнду.
Чтобы объяснить ваш пример кода:
for (String search : textSearch.getValue())
matches |= field.contains(search);
Я полагаю, что matches
- это boolean
; это означает, что побитовые операторы ведут себя так же, как логические операторы.
На каждой итерации цикла оно OR
текущее значение matches
с тем, что возвращается из field.contains()
. Это приводит к установке true
, если оно уже было true, или, если field.contains()
возвращает true.
Итак, он вычисляет, вернул ли любой вызов field.contains()
на протяжении всего цикла true
.
Ответ 2
a |= b
совпадает с a = (a | b)
Логические переменные
В контексте boolean
это означает:
if (b) {
a = true;
}
то есть если b
истинно, тогда a
будет истинным, иначе a
будет немодифицирован.
Побитовые операции
В небольшом контексте это означает, что каждый бинарный бит, установленный в b
, будет установлен в a
. Биты, которые ясны в b
, не будут изменяться в a
.
Итак, если бит 0 установлен в b
, он также будет установлен в a
, в примере ниже:
Ответ 3
Этот код:
int i = 5;
i |= 10;
эквивалентен этому коду:
int i = 5;
i = i | 10;
Аналогично, этот код:
boolean b = false;
b |= true;
эквивалентно этому:
boolean b = false;
b = b | true;
В первом примере выполняется бит-бит ИЛИ. Во втором примере выполняется логическое ИЛИ.
Ответ 4
Возможно ли, что код имеет ошибку, и это означало
matches = matches || field.contains(search);
так что совпадения должны быть true
, если хотя бы одно поле содержит переменную search
?
Ответ 5
a |= b
совпадает с a = a | b
a | b
является побитовым оператором, если оба операнда являются целыми типами (int, short и т.д.). Если оба операнда являются логическими, то он является логическим или.
Если оба a
и b
являются логическими, разница между a | b
и a || b
заключается в том, что в первом, обе стороны всегда оцениваются, в дальнейшем b
оценивается только, если a
false. Это своего рода оператор "быстрого доступа".
Это полезно для таких ситуаций:
if (a == null || a.equals(b)) { .. do something .. } // works
if (a == null | a.equals(b)) { .. do something .. } // NPE if a is null
С другой стороны, ||
фактически реализуется как еще один условный переход в байт-коде/машинный код. В некоторых случаях может быть быстрее оценивать логические условия с помощью оператора |
, чтобы избежать дополнительного скачка (и, следовательно, отложения ветвей и т.д.). Определенно что-то для низкоуровневого микро-бенчмаркинга, чтобы выяснить, что лучше (и обычно не важно в большинстве приложений).
Когда вы выполняете a |= b
, вы всегда оцениваете как a
, так и b
. На самом деле нет смысла иметь операторы a ||= b
, так как эквивалентный a = a || b
будет переводить на:
if (a) a = true;
else if (b) a = true
else a = false;
... из-за условного характера оценки ||
. Другими словами, b
не будет оцениваться, если a
уже был истинным.
Ответ 6
Этот фрагмент кода является плохим примером того, когда использовать этот оператор. Честно говоря, я не могу придумать отличный пример того, когда использовать этот оператор, но вот моя лучшая попытка:
boolean somethingIsTrue = testSomethingTrue();
if(somethingIsTrue){
//Do something
}
somethingIsTrue |= testSomethingElseTrue();
if(somethingIsTrue){
//Do something else
}
somethingIsTrue |= testSomethingElseTrue2();
if(somethingIsTrue){
//Do something else than something or something else
}
Примечание: Вам нужно 3 ifs, потому что иначе вы могли бы просто сделать somethingIsTrue | testSomethingElseTrue()
для второго, если.
Если вам интересно, почему вы не должны использовать оператор в первом примере, вот почему:
С точки зрения производительности это плохо, потому что он выполняет сравнение и присваивание для каждого цикла вместо простого сравнения. Кроме того, он продолжает итерацию, даже если будущие итерации не будут иметь эффекта (один раз matches
будет установлен в true
, он не изменится, а String.contains
не будет иметь побочных эффектов).
Он также плохой с точки зрения удобочитаемости, основанный исключительно на существовании этого вопроса;)
Таким образом, вместо этого фрагмента я бы пошел:
for (String search : textSearch.getValue()){
if(field.contains(search)){
matches = true;
break;
}
}
С одной стороны, мне кажется, что оригинальный кодер, возможно, играл слишком много code-golf, когда он написал это:)