tipos - Operadores de Java: |=bitwise OR y asignar ejemplo
operadores unarios y binarios en java (6)
Esta pregunta ya tiene una respuesta aquí:
- ¿Qué significa "| ="? (operador de tubería igual) 6 respuestas
Acabo de revisar el código que alguien ha escrito y vi |=
uso, busco operadores de Java, sugiere operaciones a modo de bit o as, ¿alguien puede explicarme y darme un ejemplo?
Aquí está el código que lo leyó:
for (String search : textSearch.getValue())
matches |= field.contains(search);
¿Podría ser posible que el código tiene un error y fue pensado
matches = matches || field.contains(search);
de modo que las coincidencias deben ser true
si al menos un campo contiene la variable de search
?
Ese fragmento de código es un mal ejemplo de cuándo usar ese operador. Honestamente, no puedo pensar en un gran ejemplo de cuándo usar este operador, pero aquí está mi mejor intento:
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
}
Nota: Necesita 3 ifs, porque de lo contrario, podría hacer somethingIsTrue | testSomethingElseTrue()
somethingIsTrue | testSomethingElseTrue()
para el segundo si.
En caso de que se esté preguntando por qué no debería usar el operador en el primer ejemplo, he aquí por qué:
Desde el punto de vista del rendimiento, es deficiente porque realiza una comparación y una asignación para cada bucle en lugar de solo una comparación. Además, continúa la iteración incluso cuando las futuras iteraciones no tendrán ningún efecto (una vez que las matches
se establecen en true
, no cambiarán y String.contains
no tiene efectos secundarios).
También es deficiente desde el punto de vista de la legibilidad, basado únicamente en la existencia de esta pregunta;)
Por lo tanto, en lugar de ese fragmento, iría por:
for (String search : textSearch.getValue()){
if(field.contains(search)){
matches = true;
break;
}
}
En una nota al margen, me parece que el codificador original podría haber estado jugando demasiado code-golf cuando (s) escribió esto :)
Este codigo
int i = 5;
i |= 10;
es equivalente a este código:
int i = 5;
i = i | 10;
Del mismo modo, este código:
boolean b = false;
b |= true;
es equivalente a este:
boolean b = false;
b = b | true;
En el primer ejemplo, se está realizando un OR a nivel de bits. En el segundo ejemplo, se realiza un OR booleano.
a |= b
es lo mismo que a = (a | b)
Variables booleanas
En un contexto boolean
, significa:
if (b) {
a = true;
}
es decir, si b
es verdadero, entonces a
será verdadero, de lo contrario a
no se modificará.
Operaciones bitwise
En un contexto de bits, significa que cada bit binario que se establece en b
se establecerá en a
. Los bits que están claros en b
no se modificarán en a
.
Entonces, si el bit 0 se establece en b
, también se establecerá en a
, según el siguiente ejemplo:
Esto establecerá el bit inferior de un entero:
a |= 0x01
Esto borrará el bit inferior:
a &= ~0x01
Esto cambiará el bit inferior:
a ^= 0x01;
a |= b
es lo mismo que a = a | b
a = a | b
a | b
a | b
es un operador bit a bit si ambos operandos son tipos integrales (int, short, etc ...). Si ambos operandos son booleanos, entonces es un booleano o.
Cuando a
y b
son booleanos, la diferencia entre a | b
a | b
a || b
a || b
es que en la primera, ambos lados siempre se evalúan, en la última b
solo se evalúa si a
es falso. Es una especie de operador de "atajo".
Esto es útil para situaciones como esta:
if (a == null || a.equals(b)) { .. do something .. } // works
if (a == null | a.equals(b)) { .. do something .. } // NPE if a is null
Por otro lado, ||
en realidad se implementa como otro salto condicional en el bytecode / machine-code. En algunos casos, puede ser más rápido evaluar las condiciones booleanas utilizando el |
Operador para evitar el salto adicional (y por lo tanto la predición de la rama, etc ...). Definitivamente, hay algo para micro-benchmarking de bajo nivel para descubrir cuál es mejor (y generalmente no es importante en la mayoría de las aplicaciones).
Cuando haces a |= b
siempre estás evaluando a
y b
. Realmente no tiene sentido tener operadores a a ||= b
, ya que el equivalente a = a || b
a = a || b
se traduciría a:
if (a) a = true;
else if (b) a = true
else a = false;
... debido a la naturaleza condicional de ||
evaluación. En otras palabras, b
no se evaluaría si a
ya fuera cierto.
a |= b;
es lo mismo que
a = (a | b);
Calcula el OR a nivel de bits de los dos operandos y asigna el resultado al operando de la izquierda.
Para explicar su código de ejemplo:
for (String search : textSearch.getValue())
matches |= field.contains(search);
Supongo que los matches
son un boolean
; esto significa que los operadores bitwise se comportan igual que los operadores lógicos.
En cada iteración del bucle, es el valor actual de matches
con lo que se devuelve desde field.contains()
. Esto tiene el efecto de establecerlo en true
si ya era cierto, o si field.contains()
devuelve verdadero.
Por lo tanto, calcula si alguna de las llamadas a field.contains()
, a lo largo de todo el bucle, ha devuelto true
.