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.