Подтвердить что ты не робот

Операторы Java: | = побитовое ИЛИ и назначить пример

Я просто просматриваю код, который написал кто-то, и я видел использование |=, глядя на Java-операторы, он предлагает поразрядные операции и назначает операцию, может ли кто-нибудь объяснить и дать мне пример?

Вот код, который его читал:

    for (String search : textSearch.getValue())
         matches |= field.contains(search);
4b9b3361

Ответ 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, в примере ниже:

  • Это установит нижний бит целого числа:

    a |= 0x01

  • Это очистит нижний бит:

    a &= ~0x01

  • Это приведет к переключению нижнего бит:

    a ^= 0x01;

Ответ 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, когда он написал это:)