Konwertuj wartość logiczną na int w Javie


350

Jaki jest najbardziej akceptowany sposób konwersji booleanna intjęzyk Java?


8
Co całkowitymi można by pomyśleć odzwierciedlał truei falseodpowiednio?
Thorbjørn Ravn Andersen

4
Niektóre języki mają domyślną konwersję z int na boolean. Java nie. Jednak oficjalna implementacja zawiera pakiety SQL i uważam, że konwertują one „false” na 0.
hpique

4
@Peter Lawrey Nie, jeśli chcesz współpracować z innymi systemami, które nie mają wartości logicznych jako nieliczbowych typów danych.
hpique

6
@Peter Lawrey Pytanie tak naprawdę nie dotyczy mapowania wartości. Chodzi o to, jak wykonać konwersję w najbardziej przejrzysty, akceptowany sposób.
hpique

7
Technicznie kompilator Java już definiuje mapowanie. Prawda i fałsz są kompilowane odpowiednio do 1 i 0.
Antimony

Odpowiedzi:


583
int myInt = myBoolean ? 1 : 0;

^^

PS: prawda = 1 i fałsz = 0


59
W przypadku, gdy myBoolean oznacza wyrażenie logiczne, użycie nawiasu jest bardziej czytelne.
rsp

40
Tak jak w (foo && (!bar || baz)) ? 1 : 0. Oczywiście, jeśli jest to tylko identyfikator, pareny nie są konieczne ani pożądane.
Blrfl,

niezła sztuczka z boolean! Szukałem, może istnieje jakiś casting, taki jak (int) true = 1, ale
zauważam

1
dla początkujących takich jak ja (boolean expression) ? 1 : 0;byłoby bardziej zrozumiałe. Myślę, że myprzedrostek wyglądał jak zmienna.
dixhom

12
@Blrfl w przykładowych nawiasach jest koniecznością , a nie kwestią czytelności. foo && (!bar || baz) ? 1 : 0byłby błąd składniowy. (Wiem, że minęło 6 lat)
Konrad Morawski


59

Korzystanie z operatora trójskładnikowego jest najprostszym, najbardziej wydajnym i najbardziej czytelnym sposobem na robienie tego, co chcesz. Zachęcam do skorzystania z tego rozwiązania.

Nie mogę się jednak oprzeć zaproponowaniu alternatywnego, przemyślanego, nieefektywnego i nieczytelnego rozwiązania.

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

Hej, ludzie lubią głosować na takie fajne odpowiedzi!

Edytować

Nawiasem mówiąc, często widziałem konwersje z wartości logicznej na int wyłącznie w celu porównania dwóch wartości (ogólnie w implementacjach compareTometody). Boolean#compareTojest właściwą drogą w tych konkretnych przypadkach.

Edytuj 2

Java 7 wprowadziła nową funkcję narzędzia, która działa bezpośrednio z typami pierwotnymi Boolean#compare(Dzięki shmosel )

int boolToInt(boolean b) {
    return Boolean.compare(b, false);
}

1
Zostaną wprowadzone przez nowoczesne JIT, więc niekoniecznie nieefektywne. Dokumentuje również, dlaczego używany jest b.compareTo, aby był czytelny.
Thorbjørn Ravn Andersen

2
Może to być powolne, ponieważ musimy zawrzeć pierwotną wartość w obiekcie. Metoda operatora trójskładnikowego działa bezpośrednio z wartościami pierwotnymi bez konwersji, więc myślę, że jest bardziej wydajna.
barjak

5
1. Możesz używać Boolean.compare()i unikać autoboxowania. 2. Dokumentacja dla Boolean.compareTo()nie mówi, że zwróci 1, a jedynie „wartość dodatnią, jeśli ten obiekt reprezentuje prawda, a argument reprezentuje fałsz”.
shmosel

1
Właśnie wykonałem test konwertujący 1 000 000 losowych wartości logicznych i ta metoda była konsekwentnie szybsza niż ta oparta na operatorze trójskładnikowym. Ogolił się około 10ms.
Mapsy

3
@AlexT. jeśli robisz mikrobenchmark, powinieneś użyć ram, aby upewnić się, że mierzysz poprawnie. Zobacz openjdk.java.net/projects/code-tools/jmh .
Thorbjørn Ravn Andersen

48
boolean b = ....; 
int i = -("false".indexOf("" + b));

14
Myślę, że lepiej by to pasowało jako komentarz, a nie odpowiedź.
hpique

164
5 - b.toString().length
kennytm

5
@ ThorbjørnRavnAndersen Tak. Używanie jednej z innych, bardziej wydajnych, opublikowanych metod, które nie wymagają tego narzutu. Chyba że możesz wyjaśnić, w jaki sposób tworzenie obiektów ciągów w celu sprawdzenia wartości logicznej jest w jakikolwiek sposób wydajne.
b1nary.atr0phy

10
@ ThorbjørnRavnAndersen Nie mam kontroli nad tym, jak używane są moje metody i jak często są one wywoływane, co jest całkowicie kwestią. Poświęcasz zarówno wydajność, jak i czytelność, co absolutnie nie przynosi wymiernych korzyści.
b1nary.atr0phy

6
Jest to zdecydowanie kreatywne, ale nie mogę wymyślić żadnej korzyści z zastosowania tej metody. Jest bardziej szczegółowy i (wydaje mi się) mniej wydajny, ale z pewnością jest interesującą metodą.
Mike Baxter

27
public int boolToInt(boolean b) {
    return b ? 1 : 0;
}

prosty


24
import org.apache.commons.lang3.BooleanUtils;
boolean x = true;   
int y= BooleanUtils.toInteger(x);

FWIW BooleanUtils.toIntegerjest zaimplementowany jako sprawiedliwy return bool ? 1 : 0;.
Solomon Ucko

Apache Commons może być przydatne, ale jest to po prostu śmieszne.
Eric Duminil

14

To zależy od sytuacji. Często najprostsze podejście jest najlepsze, ponieważ jest łatwe do zrozumienia:

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

lub

int otherThing = something ? 1 : 0;

Ale czasami warto użyć Enum zamiast flagi boolowskiej. Wyobraźmy sobie, że istnieją procesy synchroniczne i asynchroniczne:

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

W Javie wyliczanie może mieć dodatkowe atrybuty i metody:

public enum Process {

    SYNCHRONOUS (0),
    ASYNCHRONOUS (1);

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

    public int getCode() {
        return code;
    }
}

6
Dodatkowym powodem korzystania z if zamiast ?:jest to, że możesz wstawić punkty przerwania wewnątrz bloków if.
Thorbjørn Ravn Andersen

12

Jeśli używasz Apache Commons Lang (który, jak sądzę, używa go wiele projektów), możesz po prostu użyć go w następujący sposób:

int myInt = BooleanUtils.toInteger(boolean_expression); 

toIntegermetoda zwraca 1, jeśli boolean_expressionjest prawdą, 0 w przeciwnym razie


FWIW BooleanUtils.toIntegerjest zaimplementowany jako sprawiedliwy return bool ? 1 : 0;.
Solomon Ucko

8

Jeśli true -> 1i false -> 0mapowanie jest tym, czego chcesz, możesz:

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

6

Jeśli chcesz zaciemnić, użyj tego:

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

3

Pozwala zagrać z trikiem Boolean.compare(boolean, boolean). Domyślne zachowanie funkcji: jeśli obie wartości są równe, w 0przeciwnym razie zwraca -1.

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

Objaśnienie : Jak wiemy, domyślnym zwróceniem Boolean.compare jest -1 w przypadku niepoprawnego dopasowania, więc +1 ustaw wartość zwracaną na 0 dla Falsei 1 dlaTrue


3
Boolean.compare(myBoolean, false)lepiej pasowałoby do cytowanego opisu
Vadzim

@Vadzim Tak rzeczywiście wygeneruje 1 i 0, porównując z fałszem, aw obecnym scenariuszu wygeneruje 0 i -1. Oba rozwiązania są w porządku, a +1 za komentarz :-)
mumair

0

Fakt, że muszę napisać metodę otoki wokół instrukcji if do rzutowania wartości, dodaje do i tak już ogromnej listy powodów, dla których java powinna po prostu umrzeć. I widząc, że operator trójskładnikowy nie jest nawet zawinięty w funkcję, ale po prostu kopiuje wklejony wszędzie, widzę boolowską obsadę po prostu doprowadza mnie do szału. Jest to strata cykli procesora i zniewaga dla czytelności kodu.

Również większość odpowiedzi tutaj ma setki pozytywnych opinii z zerowym wyjaśnieniem, co sprawia, że ​​zgaduję, że zła praktyka jest tylko wynikiem tak częstego narażenia na java. Gdybym napisał trójskładnikowego operatora do przesyłania wartości logicznej na int w jakimkolwiek współczesnym języku, zostałbym zwolniony następnego dnia z jakiejkolwiek pracy, jaką miałem. Więc dzisiaj zrezygnowałem z prób wykorzystania rozumu przy moich zadaniach java i postanowiłem przyjąć głupotę:

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;}

-1
public static int convBool(boolean b)
{
int convBool = 0;
if(b) convBool = 1;
return convBool;
}

Następnie użyj:

convBool(aBool);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.