Convertir booleano a int en Java

350

¿Cuál es la forma más aceptada de convertir a booleana inten Java?

hpique
fuente
8
¿Qué enteros crees que corresponden truey falserespectivamente?
Thorbjørn Ravn Andersen
44
Algunos idiomas tienen conversión implícita de int a boolean. Java no lo hace. Sin embargo, la implementación oficial tiene paquetes SQL, y creo que estos convierten "falso" a 0.
hpique
44
@ Peter Lawrey No, si desea interoperar con otros sistemas que no tienen un tipo de datos booleano como no numérico.
hpique
66
@ Peter Lawrey La pregunta no es realmente sobre el mapeo de valores. Se trata de cómo hacer la conversión de la manera más clara y aceptada.
hpique
77
Técnicamente, el compilador de Java ya define una asignación. Verdadero y falso se compilan a 1 y 0 respectivamente.
Antimonio

Respuestas:

583
int myInt = myBoolean ? 1 : 0;

^^

PD: verdadero = 1 y falso = 0

Jonatha ANTOINE
fuente
59
En el caso donde myBoolean representa una expresión booleana, el uso de paréntesis es más legible.
rsp
40
Sí, como en (foo && (!bar || baz)) ? 1 : 0. Obviamente, si es solo un identificador, los padres no son necesarios ni deseables.
Blrfl
buen truco con boolean! Estaba buscando que exista algún casting como (int) true = 1, pero observando que existe así: P
mumair
1
para principiantes como yo, (boolean expression) ? 1 : 0;sería más comprensible. Creo que el myprefijo lo hizo parecer una variable.
dixhom
12
@Blrfl en sus paréntesis de ejemplo son una necesidad , no una cuestión de legibilidad. foo && (!bar || baz) ? 1 : 0Sería un error de sintaxis. (Sé que han pasado 6 años)
Konrad Morawski
150
int val = b? 1 : 0;
Grodriguez
fuente
¡Respuesta perfecta!
Gaurav
59

Usar el operador ternario es la forma más simple, más eficiente y más legible de hacer lo que desea. Te animo a utilizar esta solución.

Sin embargo, no puedo resistirme a proponer una solución alternativa, artificial, ineficiente e ilegible.

int boolToInt(Boolean b) {
    return b.compareTo(false);
}

¡A la gente le gusta votar por respuestas tan geniales!

Editar

Por cierto, a menudo vi conversiones de un booleano a un int con el único propósito de hacer una comparación de los dos valores (generalmente, en implementaciones de compareTométodo). Boolean#compareToes el camino a seguir en esos casos específicos.

Editar 2

Java 7 introdujo una nueva función de utilidad que funciona con tipos primitivos directamente, Boolean#compare(Gracias shmosel )

int boolToInt(boolean b) {
    return Boolean.compare(b, false);
}
barjak
fuente
1
Estará en línea con los JIT modernos, por lo que no necesariamente será ineficiente. También documenta por qué se está utilizando b.compareTo para que sea legible.
Thorbjørn Ravn Andersen
2
Puede ser lento porque necesitamos encuadrar el valor primitivo en un objeto. El método del operador ternario funciona directamente con valores primitivos sin conversión, por lo que creo que es más eficiente.
barjak
55
1. Puede usar Boolean.compare()y evitar el autoboxing. 2. La documentación de Boolean.compareTo()no dice que devolverá 1, solo "un valor positivo si este objeto representa verdadero y el argumento representa falso".
shmosel
1
Acabo de hacer una prueba de conversión de 1,000,000 valores booleanos aleatorios y este método fue consistentemente más rápido que el basado en el operador ternario. Se afeitó unos 10 ms.
Mapsy
3
@AlexT. Si hace microbenchmarks, debe usar un marco para asegurarse de que mide correctamente. Ver openjdk.java.net/projects/code-tools/jmh .
Thorbjørn Ravn Andersen
48
boolean b = ....; 
int i = -("false".indexOf("" + b));
Thorbjørn Ravn Andersen
fuente
14
Creo que esto sería más adecuado como comentario, no como respuesta.
hpique
164
5 - b.toString().length
kennytm
55
@ ThorbjørnRavnAndersen Sí. Usando uno de los otros métodos, más eficientes, publicados que no requieren esa sobrecarga. A menos que pueda explicar cómo crear objetos de cadena para verificar simplemente el valor de un booleano es de alguna manera eficiente.
b1nary.atr0phy 05 de
10
@ ThorbjørnRavnAndersen No tengo control sobre cómo se usan mis métodos o con qué frecuencia se llaman, lo cual es el punto. Estás sacrificando tanto el rendimiento como la legibilidad para obtener absolutamente ningún beneficio tangible.
b1nary.atr0phy
66
Definitivamente es creativo, pero no puedo pensar en una sola ventaja al usar este método. Es más detallado y (supongo) menos eficiente, pero seguro que es un método interesante.
Mike Baxter
27
public int boolToInt(boolean b) {
    return b ? 1 : 0;
}

simple

Adán
fuente
24
import org.apache.commons.lang3.BooleanUtils;
boolean x = true;   
int y= BooleanUtils.toInteger(x);
Darkeniel
fuente
FWIW, BooleanUtils.toIntegerse implementa como justo return bool ? 1 : 0;.
Solomon Ucko
Apache Commons puede ser útil, pero esto es simplemente ridículo.
Eric Duminil
14

Eso depende de la situación. A menudo, el enfoque más simple es el mejor porque es fácil de entender:

if (something) {
    otherThing = 1;
} else {
    otherThing = 0;
}

o

int otherThing = something ? 1 : 0;

Pero a veces es útil usar una enumeración en lugar de una bandera booleana. Imaginemos que hay procesos sincrónicos y asincrónicos:

Process process = Process.SYNCHRONOUS;
System.out.println(process.getCode());

En Java, enum puede tener atributos y métodos adicionales:

public enum Process {

    SYNCHRONOUS (0),
    ASYNCHRONOUS (1);

    private int code;
    private Process (int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }
}
Hendrik Brummermann
fuente
66
Una razón adicional para usar un if en lugar de ?:es que puede poner puntos de interrupción dentro de los bloques if.
Thorbjørn Ravn Andersen
12

Si usa Apache Commons Lang (que creo que muchos proyectos lo usan), puede usarlo así:

int myInt = BooleanUtils.toInteger(boolean_expression); 

toIntegerel método devuelve 1 si boolean_expressiones verdadero, 0 de lo contrario

triForce420
fuente
FWIW, BooleanUtils.toIntegerse implementa como justo return bool ? 1 : 0;.
Solomon Ucko
8

Si true -> 1y el false -> 0mapeo es lo que quieres, puedes hacer:

boolean b = true;
int i = b ? 1 : 0; // assigns 1 to i.
codictorio
fuente
6

Si desea ofuscar, use esto:

System.out.println( 1 & Boolean.hashCode( true ) >> 1 );  // 1
System.out.println( 1 & Boolean.hashCode( false ) >> 1 ); // 0
Christian Ullenboom
fuente
3

Vamos a jugar con el truco Boolean.compare(boolean, boolean). Comportamiento predeterminado de la función: si ambos valores son iguales, devuelve lo 0contrario -1.

public int valueOf(Boolean flag) {
   return Boolean.compare(flag, Boolean.TRUE) + 1;
}

Explicación : Como sabemos, el retorno predeterminado de Boolean.compare es -1 en caso de coincidencia incorrecta, por lo que +1 hace que el valor de retorno sea 0 para Falsey 1 paraTrue

mumair
fuente
3
Boolean.compare(myBoolean, false)encajaría mejor de acuerdo con la descripción citada
Vadzim
@Vadzim Sí, de hecho, generará 1 y 0 al comparar con falso y en el escenario actual generará 0 y -1. Ambas soluciones están bien y +1 para tu comentario :-)
mumair
0

El hecho de que tenga que escribir un método de envoltorio alrededor de una declaración if para emitir un valor solo se suma a la ya enorme lista de razones por las que Java ya debería morir. Y al ver que el operador ternario ni siquiera está envuelto en una función, sino que simplemente copio pegado en todas partes, veo un molde booleano en int que me vuelve loco. Es una pérdida de ciclos de CPU y un insulto a la legibilidad del código.

Además, la mayoría de las respuestas aquí tienen cientos de votos a favor con cero explicaciones, lo que me hace adivinar que las malas prácticas son solo el resultado de estar tan expuestos a Java. Si escribiera un operador ternario para convertir booleano a int en cualquier idioma moderno, me despedirían al día siguiente de cualquier trabajo que pudiera tener. Así que hoy dejé de tratar de emplear la razón en mis tareas de Java y decidí aceptar la estupidez:

public static int booltoint(boolean nonsense) {
                                // Let's start with indenting using spaces, 16 of them to be precise
                                String[] ____int = new String[500];
                                ____int[0] = Boolean.toString(nonsense);
                                try {
                                                Thread.sleep(100); 
                                } catch (Exception e) {    }
                                Random rand = new Random();
                                int n = rand.nextInt((int)1e9);
                                int result = 0;
                                int other_Result = 1;
                                for (int i = -5; i < 2; i++) {
                                                try {
                                                                if (n == 35467247) return 5; // let's just fail with one in a billion chance
                                                                if ((5 - ____int[i].length()) == 1) {
                                                                                return ++result;
                                                                } else if(____int[i] == "false") {
                                                                                return --other_Result;
                                                                }
                                                } catch (Exception e) {
                                                                // This method will throw an exception 5 times every single time I 
                                                                // cast a boolean to int before returning an integer
                                                }
                                }
                                return (int)1e35;}
MuhsinFatih
fuente
-1
public static int convBool(boolean b)
{
int convBool = 0;
if(b) convBool = 1;
return convBool;
}

Luego use:

convBool(aBool);
Regis_AG
fuente