Conversion de booléens en nombres entiers en Java sans if-statement

Je me demande s’il existe un moyen de convertir un booléen en int sans utiliser d’instructions if (pour ne pas interrompre le pipeline). Par exemple, je pourrais écrire

int boolToInt( boolean b ){ if ( b ) return 1 return 0 

Mais je me demande s’il y a un moyen de le faire sans l’instruction if, comme celle de Python

 bool = True num = 1 * ( bool ) 

Je pense aussi que tu pourrais faire

 boolean bool = True; int myint = Boolean.valueOf( bool ).compareTo( false ); 

Cela crée un object supplémentaire, cependant, donc c’est vraiment une perte de temps et je l’ai trouvé encore plus lent que la méthode if-statement (qui n’est pas nécessairement inefficace, a juste une faiblesse).

    Vous ne pouvez utiliser un booléen que dans un if. Toutefois, cela ne signifie pas qu’il y aura une twig au niveau de l’assemblage.

    Si vous vérifiez le code compilé de cette méthode (en passant, utilisez return b ? 1 : 0; comstack exactement les mêmes instructions), vous verrez qu’il n’utilise pas de saut:

     0x0000000002672580: sub $0x18,%rsp 0x0000000002672587: mov %rbp,0x10(%rsp) ;*synchronization entry 0x000000000267258c: mov %edx,%eax 0x000000000267258e: add $0x10,%rsp 0x0000000002672592: pop %rbp 0x0000000002672593: test %eax,-0x2542599(%rip) # 0x0000000000130000 ; {poll_return} 0x00000000025b2599: retq 

    Remarque: il s’agit du serveur Hotspot 7. Vous obtiendrez peut-être des résultats différents sur un ordinateur virtuel différent.

    Utilisez l’opérateur?:: ( b ? 1 : 0 )

    Vous pouvez utiliser l’ opérateur ternaire :

     return b ? 1 : 0; 

    Si cela est considéré comme un “si”, et étant donné qu’il s’agit d’un “puzzle”, vous pouvez utiliser une carte comme celle-ci:

     return new HashMap() {{ put(true, 1); put(false, 0); }}.get(b); 

    Bien que, théoriquement, l’implémentation de HashMap n’ait pas besoin d’utiliser un if, elle le fait réellement. Néanmoins, le “si” n’est pas dans votre code.

    Bien sûr, pour améliorer les performances, vous devriez:

     private static Map map = new HashMap() {{ put(true, 1); put(false, 0); }}; 

    Puis dans la méthode:

     return map.get(b); 

    Sinon, vous pouvez utiliser la méthode Apache Commons BooleanUtils.toInteger qui fonctionne à merveille …

     // Converts a boolean to an int specifying the conversion values. static int toInteger(boolean bool, int trueValue, int falseValue) // Converts a Boolean to an int specifying the conversion values. static int toInteger(Boolean bool, int trueValue, int falseValue, int nullValue) 

    J’ai trouvé une solution par framework. Utilisez compare pour booléen.

     // b = Your boolean result // v will be 1 if b equals true, otherwise 0 int v = Boolean.compare(b, false); 

    Ce n’est pas directement possible, pas en Java de toute façon. Vous pouvez envisager d’utiliser directement un int ou un byte au lieu d’un boolean si vous devez vraiment éviter la twig.

    Il est également possible que la machine virtuelle soit suffisamment intelligente pour éliminer la twig (le if ou le ?: 🙂 elle-même dans ce cas, car la représentation interne du boolean sera probablement le littéral 1 ou 0 de toute façon. Voici un article sur l’examen du code machine natif généré pour le JDK Oracle. Si vous avez besoin de rapidité, assurez-vous d’utiliser la JVM “serveur”, car elle optimise de manière plus agressive que la “cliente”.

    Je ne peux pas dire que je recommande ceci. C’est à la fois plus lent que l’opérateur ternaire en lui-même, et c’est trop intelligent pour être qualifié de bonne programmation, mais il y a ceci:

     -Boolean.FALSE.compareTo(value) 

    Il utilise le ternaire sous les couvertures (quelques appels de méthode plus tard), mais ce n’est pas dans votre code. Pour être juste, je serais prêt à parier qu’il y a aussi une twig quelque part dans l’exécution de Python (bien que je parie probablement un centime;)).

    Puisque vous ne voulez pas de solution if / else, votre expression est parfaite, même si je la changerais légèrement

     int myint = Boolean.valueOf( bool ).compareTo( Boolean.FALSE ); 

    Boolean.valueOf (boolean b) renvoie soit Boolean.TRUE, soit Boolean.FALSE, voir API.

    Une alternative raisonnable à l’utilisation du ternaire pour éviter un “si”:

     private static Boolean[] array = {false, true}; int boolToInt( boolean b ){ return Arrays.binarySearch(array, b); } 

    Notez que je considère cette question “puzzle”, alors si je la codais moi-même, j’utiliserais le ternaire.

     int ansInt = givenBoolean ? 1 : 0; 

    Vous pouvez essayer d’utiliser un opérateur ternaire comme celui-ci

     int value = flag ? 1 : 0;