Java-операторы: | = побитовое ИЛИ и назначить пример [дубликат]

17

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

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

    for (String search : textSearch.getValue())
         matches |= field.contains(search);
    
задан Rachel 13.04.2012 в 15:47
источник

6 ответов

24
a |= b;

совпадает с

a = (a | b);

Он вычисляет побитовый OR двух операндов, а присваивает результат левому операнду.

Чтобы объяснить ваш пример кода:

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

Я предполагаю, что matches является boolean ; это означает, что побитовые операторы ведут себя так же, как логические операторы.

На каждой итерации цикла оно OR s текущее значение matches с тем, что возвращается из field.contains() . Это влияет на значение true , если оно уже было true, или , если field.contains() возвращает true.

Итак, он вычисляет, если любой вызовов field.contains() , на протяжении всего цикла, возвращается true .

    
ответ дан Graham Borland 13.04.2012 в 15:50
источник
10

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;

ответ дан Alnitak 13.04.2012 в 15:49
источник
3

Этот код:

int i = 5;
i |= 10;

эквивалентен этому коду:

int i = 5;
i = i | 10;

Аналогично, этот код:

boolean b = false;
b |= true;

эквивалентно этому:

boolean b = false;
b = b | true;

В первом примере выполняется бит-бит ИЛИ. Во втором примере выполняется логическое ИЛИ.

    
ответ дан Óscar López 13.04.2012 в 15:50
источник
1

Возможно ли, что код имеет ошибку, и это означало

matches = matches || field.contains(search);

, так что совпадения должны быть true , если хотя бы одно поле содержит переменную search ?

    
ответ дан adranale 13.04.2012 в 15:55
источник
1

a |= b совпадает с a = a | b

a | b - побитовый оператор, если оба операнда являются целыми типами (int, short и т. д.). Если оба операнда являются логическими, то он является логическим или.

Когда оба a и b являются логическими, разница между a | b и a || b заключается в том, что в первом, обе стороны оцениваются always , в последнем b оценивается только в том случае, если a является ложным. Это своего рода оператор «быстрого доступа».

Это полезно для таких ситуаций:

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 уже было истинным.

    
ответ дан ɲeuroburɳ 13.04.2012 в 16:20
источник
0

Этот фрагмент кода является плохим примером того, когда использовать этот оператор. Честно говоря, я не могу придумать отличный пример того, когда использовать этот оператор, но вот моя лучшая попытка:

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

С одной стороны, мне кажется, что исходный кодер, возможно, слишком сильно проигрывал бит код- гольф , когда он написал это:)

    
ответ дан Briguy37 13.04.2012 в 18:36
источник