Le moyen le plus propre de basculer une variable booléenne en Java?

211

Existe-t-il une meilleure façon de nier un booléen en Java qu'un simple if-else?

if (theBoolean) {
    theBoolean = false;
} else {
    theBoolean = true;
}
Kevin Griffin
la source
oh gentil, j'étais sur le point de poser la même question, bien que ma question aurait été spécifique à javascript / as3, ou ECMAScript en général je suppose ... qui sera facilement couvert par cette question.
matt lohkamp
Et s'il n'y en a pas! opérateur ??
onmyway133

Réponses:

537
theBoolean = !theBoolean;
Aaron Maenpaa
la source
16
C'est ... vraiment évident - oups! Je ne sais pas pourquoi je n'y ai pas pensé. Merci.
Kevin Griffin
! Le booléen semble être un choix naturel - peut-être à l'avenir.
matt lohkamp
21
@ypnos: !!bool == !(!(bool)) == bool.
Christoffer Hammarström
12
@ ChristofferHammarström Selon cette logique, ne devrait-on pas --integer == - (- (entier)) == entier?
user515655
1
@ user515655 - Le langage définit un --opérateur (en fait, deux d'entre eux, ainsi que deux ++opérateurs), mais ne définit pas d' !!opérateur. Si vous le souhaitez, -(-(integer))vous pouvez utiliser un espace blanc entre les deux -caractères. Mais !!analyse comme deux !opérateurs indépendamment de l'espace blanc.
Ted Hopp
164
theBoolean ^= true;

Moins de frappes si votre variable est plus longue que quatre lettres

Modifier : le code a tendance à renvoyer des résultats utiles lorsqu'il est utilisé comme termes de recherche Google. Le code ci-dessus ne fonctionne pas. Pour ceux qui en ont besoin, c'est XOR au niveau du bit comme décrit ici .

pateksan
la source
14
et il est conforme à SEC :)
Tetha
6
La concision est l'âme de l'esprit.
Paul Brinkley
7
maintenant, j'arrive à un nom-drop (syntax-drop?) XOR pour avoir l'air cool devant mes amis programmeurs. Votre réponse doit être fusionnée avec celle choisie, elles sont ensemble la perfection parfaite.
matt lohkamp
6
@ScottStanchfield Ces personnes devraient l'apprendre. Ce n'est pas difficile du tout, ce n'est pas un hack, et ne pas le savoir conduit souvent à un code merdique comme par exemple celui de cette question. C'est une vraie explosion - cinq lignes en utilisant les conventions standard!
maaartinus
4
Cette opération est également 12% plus rapide que d'autres versions comme theBoolean = !theBoolean;outheBoolean = theBoolean ? false : true;
Blaine Kasten
32

Il y a plusieurs

La manière "évidente" (pour la plupart des gens)

theBoolean = !theBoolean;

La voie "la plus courte" (la plupart du temps)

theBoolean ^= true;

La manière "la plus visuelle" (la plus incertaine)

theBoolean = theBoolean ? false : true;

Extra: basculer et utiliser dans un appel de méthode

theMethod( theBoolean ^= true );

Étant donné que l'opérateur d'affectation renvoie toujours ce qui a été attribué, cela basculera la valeur via l'opérateur au niveau du bit, puis renverra la nouvelle valeur affectée à utiliser dans l'appel de méthode.

lévite
la source
Enveloppez l'implémentation dans une fonction / méthode appelée bascule, puis il n'y a presque aucun moyen de la confondre.
Lambage
@Reiner: Pour sûr C, mais Javail n'est pas permis de mélanger booléen et entier (aussi des choses comme while(1)ne sont pas possibles en Java).
Lévite
@Lambage: Vrai, mais à la baisse, vous ne pouvez pas basculer un booléen en le passant simplement, car il n'est pas possible de passer des primitives par référence en Java. Vous devrez réaffecter le résultat de la méthode à votre variable, ou sinon créer une classe wrapper pour le booléen.
Lévite
La "voie évidente" ci-dessus est signalée par SONAR avec - Les affectations internes doivent être évitées.
Orby
2

Si vous utilisez des valeurs NULL booléennes et les considérez comme fausses, essayez ceci:

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

Si vous ne remettez pas de valeurs NULL booléennes, essayez ceci:

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

Ce sont les plus propres car ils montrent l'intention dans la signature de la méthode, sont plus faciles à lire que ! et peut être facilement débogué.

Usage

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

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

Bien sûr, si vous utilisez Groovy ou un langage qui autorise les méthodes d'extension, vous pouvez enregistrer une extension et simplement faire:

Boolean b = false
b = b.toggle() // == true
Steven Spungin
la source
Bonne approche, mais pas totalement sans ambiguïté (à mon humble avis). Pour quelqu'un utilisant / lisant juste "bascule (..)" pourrait penser, appeler la méthode (sans l'attribuer à nouveau à la variable) pourrait déjà basculer la variable sous-jacente. Il est évident pour nous de voir le code en ce moment, mais dans la vraie vie, il peut être assez difficile à déboguer. Un meilleur nom de méthode pourrait être "opposé" ou éventuellement "négation", pour rendre cela un peu plus évident; ou utilisez la première approche avec un objet Booleanet basculez-le vraiment dans la méthode (mais toujours quelque peu ambigu).
Lévite
2

Cette réponse est apparue lors de la recherche de "fonction booléenne inverti java". L'exemple ci-dessous empêchera certains outils d'analyse statique d'échouer les générations en raison de la logique de branchement. C'est utile si vous devez inverser un booléen et que vous n'avez pas construit de tests unitaires complets;)

Boolean.valueOf(aBool).equals(false)

Ou bien:

Boolean.FALSE.equals(aBool)

ou

Boolean.FALSE::equals
Paramètre docteur
la source
1
J'aime le fait que vous puissiez passer Boolean.FALSE::equalsà une fonction de cartographie au lieu d'écrire un petit lambda
Patrick Parker
0

Si vous ne faites rien de particulièrement professionnel, vous pouvez toujours utiliser une classe Util. Ex, une classe util d'un projet pour une classe.

public class Util {


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

}

puis il suffit de créer un objet Util Util u = new Util(); et d'avoir quelque chose pour le retourSystem.out.println( u.flip(bool) );

Si vous allez finir par utiliser la même chose encore et encore, utilisez une méthode, et surtout si c'est sur plusieurs projets, créez une classe Util. Je ne sais pas quelle est la norme de l'industrie. (Les programmeurs expérimentés se sentent libres de me corriger)

Will D.
la source
-4

Avant:

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

Après:

boolean result = isresult();
result ^= true;
Nikhil Kumar
la source
Qui a jamais voté contre? Pouvez-vous également expliquer la raison?
Nikhil Kumar
11
Deux raisons principales pour lesquelles je peux penser à la raison pour laquelle quelqu'un pourrait vous avoir dévalorisé: 1) Nécromancie de fil ( allez! La question a été posée il y a 7 (!) Ans! ) & Votre réponse n'apporte rien de nouveau à la table; 2) L'électeur s'attendait à quelque chose de "plus propre" ( lire: plus court ) - la réponse d'AaronMaenpaa en est un parfait exemple.
Priidu Neemre
5
@Elltz: Au contraire - je l'ai en fait voté, car la réponse était techniquement correcte. Cependant, je dois dire que je n'apprécie pas la tendance à pirater les réponses des utilisateurs précédents pour du karma bon marché (voir la réponse de nlaq).
Priidu Neemre
@PriiduNeemre, question posée et réponse acceptée avant 7+ ans et pensez-vous que, sauf sur votre liste, quelqu'un abandonnera-t-il? en dehors de cela, votre réponse n'est pas non plus à la hauteur .. :(
user1140237
2
après: résultat booléen =! isresult ();
Petter Friberg