java - operadores - ¿Es una buena práctica usar el operador xor para verificaciones booleanas?
operadores logicos en java ejemplos (13)
Personalmente me gusta el operador exclusivo o ^
, cuando tiene sentido en el contexto de los controles booleanos debido a su concisión. Yo prefiero escribir
if (boolean1 ^ boolean2)
{
//do it
}
que
if((boolean1 && !boolean2) || (boolean2 && !boolean1))
{
//do it
}
pero a menudo obtengo miradas confusas de otros desarrolladores experimentados de Java (no solo de los novatos), y algunas veces comentan cómo solo debe usarse para operaciones bit a bit.
Tengo curiosidad sobre las mejores prácticas con respecto al uso del operador ^
.
! = está bien para comparar dos variables. Sin embargo, no funciona con comparaciones múltiples.
Como operador bit a bit, xor es mucho más rápido que cualquier otro medio para reemplazarlo. Por lo tanto, para cálculos críticos y escalables de rendimiento, xor es imprescindible.
Mi opinión personal subjetiva: está absolutamente prohibido, para cualquier propósito, usar igualdad (== o! =) Para booleanos. Su uso muestra la falta de principios y principios básicos de programación. Cualquiera que le dé miradas confundidas debería volver a lo básico del álgebra booleana (tuve la tentación de escribir "a los ríos de la creencia" aquí :)).
Con la claridad del código en mente, mi opinión es que el uso de XOR en las comprobaciones booleanas no es un uso típico para el operador bit a bit XOR. Desde mi experiencia, el XOR bit a bit en Java se usa generalmente para implementar un comportamiento de flag toggle
máscara:
flags = flags ^ MASK;
This artículo de Vipan Singla explica el caso de uso más en detalle.
Si necesita usar XOR bit a bit como en su ejemplo, coméntele por qué lo usa, ya que es probable que requiera que incluso una audiencia alfabetizada bit a bit se detenga en sus pistas para comprender por qué lo está utilizando.
Creo que estaría bien si lo comentaras, por ejemplo, // ^ == XOR
.
Creo que ha respondido a su propia pregunta: si obtiene un aspecto extraño de las personas, probablemente sea más seguro optar por la opción más explícita.
Si necesita comentarlo, entonces es mejor que lo reemplace con la versión más detallada y no haga que la gente haga la pregunta en primer lugar.
Me parece que tengo conversaciones similares mucho. Por un lado, tiene un método compacto y eficiente para lograr su objetivo. Por otro lado, tiene algo que el resto de su equipo podría no entender, lo que dificulta su mantenimiento en el futuro.
Mi regla general es preguntar si la técnica utilizada es algo que es razonable esperar que los programadores en general conozcan. En este caso, creo que es razonable esperar que los programadores sepan cómo usar operadores booleanos, por lo que usar xor en una declaración if es correcto.
Como ejemplo de algo que no estaría bien, tome el truco de usar xor para intercambiar dos variables sin usar una variable temporal. Ese es un truco con el que no espero que todos estén familiarizados, por lo que no pasaría la revisión del código.
Personalmente prefiero la expresión "boolean1 ^ boolean2" debido a su brevedad.
Si estuviera en su situación (trabajando en equipo), alcanzaría un compromiso al encapsular la lógica "boolean1 ^ boolean2" en una función con un nombre descriptivo como "isDifferent (boolean1, boolean2)".
Por ejemplo, en lugar de usar "boolean1 ^ boolean2", llamaría a "isDifferent (boolean1, boolean2)" de la siguiente manera:
if (isDifferent(boolean1, boolean2))
{
//do it
}
Su función "isDifferent (boolean1, boolean2)" se verá así:
private boolean isDifferent(boolean1, boolean2)
{
return boolean1 ^ boolean2;
}
Por supuesto, esta solución implica el uso de una llamada de función ostensiblemente extraña, que en sí misma está sujeta al escrutinio de Mejores Prácticas, pero evita la expresión detallada (y fea) "(boolean1 &&! Boolean2) || (boolean2 &&! Boolean1) "¡!
Recientemente utilicé un xor en un proyecto de JavaScript en el trabajo y terminé agregando 7 líneas de comentarios para explicar lo que estaba sucediendo. La justificación para usar xor en ese contexto fue que uno de los términos (término 1 en el ejemplo siguiente) podría tomar no dos sino tres valores: undefined
, true
o false
mientras que el otro ( term2
) podría ser true
o false
. Hubiera tenido que agregar una verificación adicional para los casos undefined
pero con xor, la siguiente fue suficiente ya que el xor obliga al primer término a evaluarse primero como un booleano, dejando que undefined
sea tratado como false
:
if (term1 ^ term2) { ...
Fue, al final, un poco exagerado, pero quería mantenerlo allí de todos modos, como una especie de huevo de pascua.
Si el patrón de uso lo justifica, ¿por qué no? Si bien su equipo no reconoce al operador de inmediato, con el tiempo podrían hacerlo. Los humanos aprenden nuevas palabras todo el tiempo. ¿Por qué no en la programación?
La única precaución que podría indicar es que "^" no tiene la semántica de cortocircuito de su segunda verificación booleana. Si realmente necesita la semántica de cortocircuito, entonces un método de utilidad estático también funciona.
public static boolean xor(boolean a, boolean b) {
return (a && !b) || (b && !a);
}
Siempre puedes envolverlo en una función para darle un nombre detallado:
public static boolean XOR(boolean A, boolean B) {
return A ^ B;
}
Pero, me parece que no sería difícil para alguien que no supiera lo que el operador es para Google hacerlo realmente rápido. No será difícil de recordar después de la primera vez. Como solicitó otros usos, es común usar el XOR para enmascarar bits.
También puede usar XOR para intercambiar los valores en dos variables sin usar una tercera variable temporal .
// Swap the values in A and B
A ^= B;
B ^= A;
A ^= B;
Aquí hay una pregunta de relacionada con el intercambio XOR .
Simplemente puede usar !=
lugar.
if((boolean1 && !boolean2) || (boolean2 && !boolean1))
{
//do it
}
En mi humilde opinión, este código podría simplificarse:
if(boolean1 != boolean2)
{
//do it
}
str.contains("!=") ^ str.startsWith("not(")
se ve mejor para mí que
str.contains("!=") != str.startsWith("not(")