Est-ce une bonne pratique d'utiliser l'opérateur xor pour les vérifications booléennes?

j'aime personnellement le exclusif ou , ^ , opérateur quand il a du sens dans le contexte des contrôles booléens en raison de sa concision. Je préfère de beaucoup à l'écriture de

if (boolean1 ^ boolean2)
{
  //do it
}

que

if((boolean1 && !boolean2) || (boolean2 && !boolean1))
{
  //do it
}

mais je reçois souvent des regards confus d'autres développeurs Java expérimentés (pas seulement les débutants), et parfois des commentaires sur la façon dont il devrait être utilisé uniquement pour les opérations bitwise.

Je suis curieux de connaître les meilleures pratiques concernant l'utilisation de la ^ de l'opérateur.

142
demandé sur nbro 2008-10-02 06:58:12

13 réponses

vous pouvez simplement utiliser != à la place.

285
répondu vaxquis 2017-10-20 20:29:34

je pense que vous avez répondu à votre propre question - si vous obtenez des regards étranges de personnes, il est probablement plus sûr d'aller avec l'option plus explicite.

si vous avez besoin de le commenter, alors vous êtes probablement mieux de le remplacer par la version plus verbeuse et de ne pas faire les gens de poser la question en premier lieu.

27
répondu Martin 2008-10-02 03:34:54

je trouve que j'ai beaucoup de conversations similaires. D'une part, vous avez une méthode compacte et efficace pour atteindre votre objectif. D'autre part, vous avez quelque chose que le reste de votre équipe pourrait ne pas comprendre, ce qui rend difficile de maintenir à l'avenir.

ma règle générale est de demander si la technique utilisée est quelque chose qu'il est raisonnable d'attendre des programmeurs en général de savoir. Dans ce cas, je pense qu'il est raisonnable de s'attendre à des programmeurs de savoir comment utiliser les opérateurs booléens, donc utiliser xor dans une instruction if est correct.

comme exemple de quelque chose qui ne serait pas correct, prenez l'astuce d'utiliser xor pour échanger deux variables sans utiliser une variable temporaire. C'est un truc que je ne m'attendais pas à ce que tout le monde soit familier avec, donc ça ne passerait pas la revue du code.

16
répondu Dave Tarkowski 2018-02-22 20:23:20

je pense que vous pouvez le commenter, par exemple // ^ == XOR .

14
répondu Dre 2018-02-22 20:18:38

vous pourriez toujours l'envelopper dans une fonction pour lui donner un nom verbeux:

public static boolean XOR(boolean A, boolean B) {
    return A ^ B;
}

mais, il me semble qu'il ne serait pas difficile pour quelqu'un qui ne savait pas ce que l'opérateur ^ est destiné à Google vraiment rapide. Ce ne sera pas difficile de s'en souvenir après la première fois. Puisque vous avez demandé d'autres utilisations, il est courant d'utiliser le XOR pour masquage de bits.

vous pouvez aussi utiliser XOR pour échanger les valeurs en deux variables sans en utilisant une troisième variable temporaire .

// Swap the values in A and B
A ^= B;
B ^= A;
A ^= B;

Voici une question de débordement lié à l'échange de XOR .

8
répondu Cory Gross 2017-06-21 13:45:20

j'ai récemment utilisé un xor dans un projet JavaScript au travail et a fini par ajouter 7 lignes de commentaires pour expliquer ce qui se passait. La justification de l'utilisation de xor dans ce contexte était que l'un des termes ( term1 dans l'exemple ci-dessous) pouvait prendre non pas deux mais trois valeurs: undefined , true ou false tandis que l'autre ( term2 ) pouvait être true ou false . J'aurais dû ajouter un contrôle supplémentaire pour les undefined cas mais avec xor, le suivant était suffisant puisque le xor force le premier terme à être d'abord évalué comme un booléen, en laissant undefined obtenir traité comme false :

if (term1 ^ term2) { ...

Il était, à la fin, un peu exagéré, mais je voulais le garder là de toute façon, comme une sorte de un oeuf de pâques.

6
répondu Ates Goral 2018-02-22 20:27:21

avec la clarté du code à l'esprit, mon opinion est que l'utilisation de XOR dans les vérifications booléennes n'est pas une utilisation typique pour l'opérateur XOR bitwise. D'après mon expérience, bitwise XOR en Java est typiquement utilisé pour mettre en œuvre un masque flag toggle comportement:

flags = flags ^ MASK;

cet article de Vipan Singla explique plus en détail le cas d'utilisation.

si vous devez utiliser bitwise XOR comme dans votre exemple, commentez pourquoi vous utilisez-le, car il est susceptible de nécessiter même un public instruit bitwise arrêter dans leurs pistes pour comprendre pourquoi vous l'utilisez.

5
répondu Gunnar Karlsson 2018-02-22 20:21:19
if((boolean1 && !boolean2) || (boolean2 && !boolean1)) 
{ 
  //do it 
} 

IMHO ce code pourrait être simplifié:

if(boolean1 != boolean2) 
{ 
  //do it 
} 
4
répondu Y-- 2010-04-10 08:33:35

si l'usage le justifie, pourquoi pas? Bien que votre équipe ne reconnaisse pas l'opérateur tout de suite, avec le temps ils pourraient. Les humains apprennent de nouveaux mots tout le temps. Pourquoi pas dans la programmation?

la seule mise en garde que je puisse formuler est que " ^ " n'a pas la sémantique de court-circuit de votre deuxième vérification booléenne. Si vous avez vraiment besoin de la sémantique du court-circuit, alors une méthode util statique fonctionne aussi.

public static boolean xor(boolean a, boolean b) {
    return (a && !b) || (b && !a);
}
-1
répondu Alan 2008-10-02 03:08:30

personnellement, je préfère l'expression "boolean1 ^ boolean2" en raison de sa concision.

si j'étais dans votre situation (travaillant en équipe), je trouverais un compromis en encapsulant la logique" boolean1 ^ boolean2 "dans une fonction avec un nom descriptif tel que"isDifferent(boolean1, boolean2)".

par exemple, au lieu d'utiliser "boolean1 ^ boolean2", vous appelleriez "isDifferent (boolean1, boolean2)" comme ceci:

if (isDifferent(boolean1, boolean2))
{
  //do it
}

Votre "est différent(boolean1, boolean2)" fonction ressemblerait à:

private boolean isDifferent(boolean1, boolean2)
{
    return boolean1 ^ boolean2;
}

bien sûr, cette solution implique l'utilisation d'une fonction ostensiblement extrinsèque appel, qui est en soi soumis à l'examen des meilleures pratiques, mais il évite l'expression verbeuse (et laid) " (boolean1 && !boolean2) / / (boolean2&&!boolean1)"!

-1
répondu ONE 2017-08-12 04:39:17

!= est OK pour comparer deux variables. Cela ne fonctionne pas, cependant, avec des comparaisons multiples.

-3
répondu 2009-02-05 10:13:25
str.contains("!=") ^ str.startsWith("not(")

me semble mieux que

str.contains("!=") != str.startsWith("not(")
-3
répondu Chris Rea 2011-01-25 13:07:45

en tant qu'opérateur bitwise, xor est beaucoup plus rapide que tout autre moyen pour le remplacer. Donc, pour les calculs critiques et évolutifs de la performance, xor est impératif.

mon opinion personnelle subjective: il est absolument interdit, à quelque fin que ce soit, d'utiliser l'égalité (== or !=) pour les booléens. Le fait de l'utiliser montre un manque d'éthique et de principes de base en matière de programmation. Quiconque vous donne des regards confus sur ^ devrait être renvoyé aux bases de l'algèbre booléenne (j'ai été tenté d'écrire "les rivières de la croyance" ici :) ).

-3
répondu Nick 2011-03-24 16:44:09