¿La forma más limpia de alternar una variable booleana en Java?

211

¿Hay una mejor manera de negar un booleano en Java que un simple if-else?

if (theBoolean) {
    theBoolean = false;
} else {
    theBoolean = true;
}
Kevin Griffin
fuente
Oh, bueno, estaba a punto de hacer la misma pregunta, aunque mi pregunta habría sido específica para javascript / as3, o ECMAScript en general, supongo ... lo que será fácilmente cubierto por esta pregunta.
Matt Lohkamp
¿Qué pasa si no hay! operador ??
onmyway133

Respuestas:

537
theBoolean = !theBoolean;
Aaron Maenpaa
fuente
16
Eso es ... realmente obvio, ¡Uy! No sé por qué no lo pensé. Gracias.
Kevin Griffin
! Boolean parece una opción natural, tal vez en el futuro.
Matt Lohkamp
21
@ypnos: !!bool == !(!(bool)) == bool.
Christoffer Hammarström
12
@ ChristofferHammarström Según esa lógica, entonces no debería --integer == - (- (entero)) == entero?
user515655
1
@ user515655: el lenguaje define un --operador (en realidad, dos de ellos, junto con dos ++operadores), pero no define un !!operador. Si lo desea -(-(integer)), puede usar espacios en blanco entre los dos -caracteres. Pero se !!analiza como dos !operadores independientemente del espacio en blanco.
Ted Hopp
164
theBoolean ^= true;

Menos pulsaciones de teclas si su variable tiene más de cuatro letras

Editar : el código tiende a devolver resultados útiles cuando se usa como términos de búsqueda de Google. El código anterior no lo hace. Para aquellos que lo necesitan, es XOR bit a bit como se describe aquí .

pateksan
fuente
14
y se ajusta a DRY :)
Tetha
66
La brevedad es el alma del ingenio.
Paul Brinkley
77
ahora puedo usar XOR sin nombre (¿sintaxis-soltar?) XOR para lucir genial frente a mis amigos programadores. Su respuesta debe fusionarse con la elegida, juntas son pura perfección.
Matt Lohkamp
66
@ScottStanchfield Dichas personas deberían aprenderlo. No es difícil en absoluto, no es un truco, y no saberlo a menudo conduce a un código malo como, por ejemplo, el de esta pregunta. Esta es una verdadera explosión: ¡cinco líneas con las convenciones estándar!
maaartinus
44
Esta operación también es un 12% más rápida que otras versiones como theBoolean = !theBoolean;otheBoolean = theBoolean ? false : true;
Blaine Kasten
32

Hay varios

La forma "obvia" (para la mayoría de las personas)

theBoolean = !theBoolean;

El camino "más corto" (la mayoría de las veces)

theBoolean ^= true;

La forma "más visual" (más incierta)

theBoolean = theBoolean ? false : true;

Extra: alternar y usar en una llamada de método

theMethod( theBoolean ^= true );

Dado que el operador de asignación siempre devuelve lo que se le ha asignado, esto alternará el valor a través del operador bit a bit y luego devolverá el nuevo valor asignado para ser utilizado en la llamada al método.

Levita
fuente
Envuelva la implementación en una función / método llamado alternar y casi no hay forma de confundirlo.
Lambage
@Reiner: CDefinitivamente, pero en Javaél no está permitido mezclar booleano y entero (también cosas como while(1)no son posibles en Java).
Levite
@Lambage: es cierto, pero a la baja no puede alternar un booleano simplemente pasándolo, ya que no es posible pasar primitivas por referencia en Java. Tendría que reasignar el resultado del método a su variable, o de lo contrario crear una clase de contenedor para el booleano.
Levite
La "forma obvia" anterior es marcada por SONAR con: las tareas internas deben evitarse.
Orby
2

Si usa valores booleanos NULL y los considera falsos, intente esto:

static public boolean toggle(Boolean aBoolean) {
    if (aBoolean == null) return true;
    else return !aBoolean;
}

Si no está entregando valores booleanos NULL, intente esto:

static public boolean toggle(boolean aBoolean) {
   return !aBoolean;
}

¡Estos son los más limpios porque muestran la intención en la firma del método, son más fáciles de leer en comparación con ! operador, y se puede depurar fácilmente.

Uso

boolean bTrue = true
boolean bFalse = false
boolean bNull = null

toggle(bTrue) // == false
toggle(bFalse) // == true
toggle(bNull) // == true

Por supuesto, si usa Groovy o un lenguaje que permite métodos de extensión, puede registrar una extensión y simplemente hacer:

Boolean b = false
b = b.toggle() // == true
Steven Spungin
fuente
Buen enfoque, pero no totalmente inequívoco (en mi humilde opinión). Para alguien que usa / leer solo "alternar (..)" podría pensar, llamar al método (sin asignarlo nuevamente a la variable) ya podría alternar la variable subyacente. Es obvio para nosotros en este momento ver el código, pero en la vida real puede ser bastante difícil de depurar. Un mejor nombre de método podría ser "opuesto" o posiblemente "negación", para hacerlo más obvio; o usar el primer enfoque con un objeto Booleany realmente alternarlo dentro del método (pero todavía algo ambiguo).
Levite
2

Esta respuesta surgió al buscar "función booleana invertida de Java". El siguiente ejemplo evitará que ciertas herramientas de análisis estático fallen las compilaciones debido a la lógica de ramificación. Esto es útil si necesita invertir un valor booleano y no ha desarrollado pruebas unitarias completas;)

Boolean.valueOf(aBool).equals(false)

o alternativamente:

Boolean.FALSE.equals(aBool)

o

Boolean.FALSE::equals
Parámetro médico
fuente
1
Me gusta el hecho de que podría pasar Boolean.FALSE::equalsa una función de mapeo en lugar de escribir una pequeña lambda
Patrick Parker
0

Si no está haciendo nada particularmente profesional, siempre puede usar una clase Util. Por ejemplo, una clase util de un proyecto para una clase.

public class Util {


public Util() {}
public boolean flip(boolean bool) { return !bool; }
public void sop(String str) { System.out.println(str); }

}

entonces solo crea un objeto Util Util u = new Util(); y tenga algo para devolverSystem.out.println( u.flip(bool) );

Si va a terminar usando lo mismo una y otra vez, use un método, y especialmente si se trata de proyectos, haga una clase de Util. Sin embargo, no sé cuál es el estándar de la industria. (Los programadores experimentados pueden corregirme)

Will D.
fuente
-4

Antes de:

boolean result = isresult();
if (result) {
    result = false;
} else {
    result = true;
}

Después:

boolean result = isresult();
result ^= true;
Nikhil Kumar
fuente
¿Quién ha votado en contra? ¿Puedes explicar la razón también?
Nikhil Kumar
11
Hay dos razones principales por las que puedo pensar por qué alguien podría haberle rechazado: 1) Hilo de nigromancia (¡ vamos! ¡La pregunta se hizo hace 7 (!) Años! ) Y su respuesta no trae nada nuevo a la mesa; 2) El votante esperaba algo "más limpio" ( léase: más corto ): la respuesta de AaronMaenpaa es un excelente ejemplo de esto.
Priidu Neemre
55
@Elltz: Por el contrario, en realidad lo he votado, ya que la respuesta fue técnicamente correcta. Sin embargo, debo decir que no disfruto la tendencia de contrabando de respuestas de usuarios anteriores por karma barato (ver la respuesta de nlaq).
Priidu Neemre
@PriiduNeemre, la pregunta formulada y la respuesta se aceptan antes de los 7 años o más, ¿cree que, excepto en su lista, alguien dará su voto? aparte de esto, su respuesta tampoco está a la
altura
2
después: resultado booleano =! isresult ();
Petter Friberg