Najczystszy sposób przełączania zmiennej boolean w Javie?


211

Czy istnieje lepszy sposób na zanegowanie wartości logicznej w Javie niż zwykły if-else?

if (theBoolean) {
    theBoolean = false;
} else {
    theBoolean = true;
}

och, miło, miałem właśnie zadać to samo pytanie, chociaż moje pytanie dotyczyłoby javascript / as3 lub ogólnie ECMAScript, jak sądzę ... które z łatwością można ująć w to pytanie.
matt lohkamp

Co jeśli nie ma! operator?
onmyway133

Odpowiedzi:


537
theBoolean = !theBoolean;

16
To ... naprawdę oczywiste - ups! Nie wiem, dlaczego o tym nie pomyślałem. Dzięki.
Kevin Griffin

! Boolean wydaje się naturalnym wyborem - może w przyszłości.
matt lohkamp

21
@ypnos: !!bool == !(!(bool)) == bool.
Christoffer Hammarström

12
@ ChristofferHammarström Zgodnie z tą logiką nie powinno --integer == - (- (liczba całkowita)) == liczba całkowita?
user515655,

1
@ user515655 - Język definiuje --operatora (w rzeczywistości dwóch z nich wraz z dwoma ++operatorami), ale nie definiuje !!operatora. Jeśli chcesz -(-(integer)), możesz użyć spacji między dwoma -znakami. Ale !!parsuje jako dwa !operatory niezależnie od białych znaków.
Ted Hopp

164
theBoolean ^= true;

Mniej naciśnięć klawiszy, jeśli zmienna ma więcej niż cztery litery

Edycja : kod zwykle zwraca przydatne wyniki, gdy jest używany jako wyszukiwane hasło Google. Powyższy kod nie. Dla tych, którzy go potrzebują, jest to bitowy XOR, jak opisano tutaj .


14
i jest zgodny z DRY :)
Tetha

6
Zwięzłość jest duszą dowcipu.
Paul Brinkley

7
teraz przechodzę do XOR-up-name-drop-drop-syntax-drop ?, żeby wyglądać fajnie przed moimi programistami. Twoja odpowiedź powinna zostać połączona z wybraną, razem są czystą doskonałością.
matt lohkamp

6
@ScottStanchfield Tacy ludzie powinni się tego nauczyć. To wcale nie jest trudne, nie jest hackowaniem, a nie wiedząc, że często prowadzi do gównianego kodu, jak np. To pytanie. To jest prawdziwy wysadzenie - pięć linii przy użyciu standardowych konwencji!
maaartinus

4
Ta operacja jest również o 12% szybsza niż w innych wersjach, takich jak theBoolean = !theBoolean;lubtheBoolean = theBoolean ? false : true;
Blaine Kasten

32

Istnieje kilka

„Oczywisty” sposób (dla większości osób)

theBoolean = !theBoolean;

„Najkrótsza” droga (przez większość czasu)

theBoolean ^= true;

„Najbardziej wizualny” sposób (najbardziej niepewny)

theBoolean = theBoolean ? false : true;

Dodatkowo: Przełącz i używaj w wywołaniu metody

theMethod( theBoolean ^= true );

Ponieważ operator przypisania zawsze zwraca to, co zostało przypisane, spowoduje to przełączenie wartości za pomocą operatora bitowego, a następnie zwróci nowo przypisaną wartość do użycia w wywołaniu metody.


Zawiń implementację w funkcję / metodę o nazwie toggle, a wtedy prawie nie ma sposobu, aby ją pomylić.
Lambage

@ Reeiner: Na Cpewno, ale w Javanim nie wolno mieszać wartości logicznych i całkowitych (również takie rzeczy while(1)nie są możliwe w Javie).
Lewita

@Lambage: To prawda, ale z drugiej strony nie można przełączać wartości logicznej, po prostu przekazując ją, ponieważ nie można przekazywać prymitywów przez referencję w Javie. Trzeba będzie ponownie przypisać wynik metody do zmiennej lub w inny sposób utworzyć klasę opakowania dla wartości logicznej.
Lewita

„Oczywisty sposób” powyżej został oznaczony przez SONAR przy pomocy - Należy unikać przypisań wewnętrznych.
Orby

2

Jeśli używasz boolowskich wartości NULL i uznajesz je za fałszywe, spróbuj tego:

static public boolean toggle(Boolean aBoolean) {
    if (aBoolean == null) return true;
    else return !aBoolean;
}

Jeśli nie przekazujesz boolowskich wartości NULL, spróbuj tego:

static public boolean toggle(boolean aBoolean) {
   return !aBoolean;
}

Są to najczystsze, ponieważ pokazują intencję w metodzie, są łatwiejsze do odczytania w porównaniu do ! operatora i można go łatwo debugować.

Stosowanie

boolean bTrue = true
boolean bFalse = false
boolean bNull = null

toggle(bTrue) // == false
toggle(bFalse) // == true
toggle(bNull) // == true

Oczywiście, jeśli używasz Groovy lub języka, który pozwala na metody rozszerzeń, możesz zarejestrować rozszerzenie i po prostu zrobić:

Boolean b = false
b = b.toggle() // == true

Dobre podejście, ale nie całkowicie jednoznaczne (imho). Dla kogoś, kto używa / czyta tylko „przełącznik (..)”, może pomyśleć, wywołanie metody (bez przypisywania jej ponownie do zmiennej) może już przełączyć zmienną bazową. Teraz jest dla nas oczywiste, że widzimy kod, ale w prawdziwym życiu może być dość trudny do debugowania. Lepszą nazwą metody może być „przeciwieństwo” lub ewentualnie „negacja”, aby uczynić to nieco bardziej oczywistym; lub użyj pierwszego podejścia z obiektem Booleani naprawdę przełącz go w ramach metody (ale nadal nieco niejednoznacznej).
Lewita

2

Ta odpowiedź pojawiła się podczas wyszukiwania „jaolowej inwertowanej funkcji boolean”. Poniższy przykład zapobiegnie niepowodzeniom niektórych narzędzi analizy statycznej z powodu logiki rozgałęziania. Jest to przydatne, jeśli trzeba odwrócić wartość logiczną i nie opracowano kompleksowych testów jednostkowych;)

Boolean.valueOf(aBool).equals(false)

lub alternatywnie:

Boolean.FALSE.equals(aBool)

lub

Boolean.FALSE::equals

1
Podoba mi się to, że można przejść Boolean.FALSE::equalsdo funkcji mapowania zamiast pisać małą lambda
Patrick Parker

0

Jeśli nie robisz nic szczególnie profesjonalnego, zawsze możesz skorzystać z klasy Util. Ex, klasa util z projektu dla klasy.

public class Util {


public Util() {}
public boolean flip(boolean bool) { return !bool; }
public void sop(String str) { System.out.println(str); }

}

następnie po prostu utwórz obiekt Util Util u = new Util(); i coś do zwrotuSystem.out.println( u.flip(bool) );

Jeśli będziesz używać tej samej metody w kółko, użyj metody, a zwłaszcza, jeśli dotyczy to różnych projektów, stwórz klasę Util. Nie wiem jednak, jaki jest standard branżowy. (Doświadczeni programiści mogą mnie poprawić)



-4

Przed:

boolean result = isresult();
if (result) {
    result = false;
} else {
    result = true;
}

Po:

boolean result = isresult();
result ^= true;

Kto kiedykolwiek przegłosował? Czy możesz również wyjaśnić powód?
Nikhil Kumar

11
Dwa główne powody, dla których mogę wymyślić, dlaczego ktoś cię ocenił: 1) Nekromancja wątku ( daj spokój ! Pytanie zostało zadane 7 (!) Lat temu! ) I twoja odpowiedź nie wnosi nic nowego do stołu; 2) Wyborca ​​oczekiwał czegoś „czystszego” ( czytaj: krótszy ) - odpowiedź AaronaMaenpaa jest tego najlepszym przykładem.
Priidu Neemre

5
@Elltz: Wręcz przeciwnie - głosowałem go, ponieważ odpowiedź była technicznie poprawna. Muszę jednak powiedzieć, że nie podoba mi się trend polegający na tym, że bootlegging odpowiedzi poprzednich użytkowników na tanią karmę (patrz odpowiedź nlaq).
Priidu Neemre

@PriiduNeemre, pytanie zadane i odpowiedź zaakceptowane przed 7+ latami i czy uważasz, że poza listą ktoś da głos? poza tym twoja odpowiedź również nie jest do znaku .. :(
user1140237

2
after: wynik boolowski =! isresult ();
Petter Friberg,
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.