Самый простой способ переключить логическую переменную в Java?

211

Есть ли лучший способ отрицать логическое значение в Java, чем простой if-else?

if (theBoolean) {
    theBoolean = false;
} else {
    theBoolean = true;
}
Кевин Гриффин
источник
о, хорошо, я собирался задать тот же вопрос, хотя мой вопрос был бы специфичным для javascript / as3 или ECMAScript в целом, я полагаю ... который легко охватывается этим вопросом.
Мэтт Лохкамп
Что делать, если нет! оператор ??
onmyway133

Ответы:

537
theBoolean = !theBoolean;
Аарон Маенпаа
источник
16
Это ... действительно очевидно - упс! Не знаю, почему я не подумал об этом. Спасибо.
Кевин Гриффин
! Boolean кажется естественным выбором - возможно, в будущем.
Мэтт Лохкамп
21
@ypnos: !!bool == !(!(bool)) == bool.
Христоффер Хаммарстрем
12
@ ChristofferHammarström По этой логике не следует --integer == - (- (целое число)) == целое число?
user515655 11.12.15
1
@ user515655 - Язык определяет --оператор (фактически два из них вместе с двумя ++операторами), но не определяет !!оператор. Если вы хотите, -(-(integer))вы можете использовать пробел между двумя -символами. Но !!разбирается как два !оператора независимо от пробела.
Тед Хопп
164
theBoolean ^= true;

Меньше нажатий клавиш, если ваша переменная длиннее четырех букв

Изменить : код имеет тенденцию возвращать полезные результаты при использовании в качестве поисковых терминов Google. Код выше не делает. Для тех, кому это нужно, это побитовый XOR, как описано здесь .

pateksan
источник
14
и это соответствует DRY :)
Tetha
6
Краткость - это душа остроумия.
Пол Бринкли
7
теперь я получаю бесцеремонное падение имени (синтаксис-падение?) XOR, чтобы выглядеть круто перед моими друзьями-программистами. Ваш ответ должен быть объединен с избранным, вместе они являются чистым совершенством.
Мэтт Лохкамп
6
@ScottStanchfield Такие люди должны учиться этому. Это совсем не сложно, это не хак, и незнание этого часто приводит к дрянному коду, как, например, этот вопрос. Это настоящий взрыв - пять строк с использованием стандартных соглашений!
Maaartinus
4
Эта операция также на 12% быстрее, чем другие версии, такие как theBoolean = !theBoolean;илиtheBoolean = theBoolean ? false : true;
Блейн Кастен,
32

Есть несколько

«Очевидный» способ (для большинства людей)

theBoolean = !theBoolean;

Самый короткий путь (большую часть времени)

theBoolean ^= true;

«Самый наглядный» способ (самый неуверенный)

theBoolean = theBoolean ? false : true;

Дополнительно: переключение и использование в вызове метода

theMethod( theBoolean ^= true );

Так как оператор присваивания всегда возвращает то, что было назначено, это переключит значение с помощью побитового оператора, а затем вернет вновь присвоенное значение, которое будет использовано в вызове метода.

левит
источник
Оберните реализацию в функцию / метод, называемую toggle, и тогда ее почти невозможно будет перепутать.
Lambage
@Reiner: Определенно C, но в Javaнем нельзя смешивать булево и целое число (такие вещи как while(1)невозможны в Java).
Левит
@Lambage: Верно, но с другой стороны вы не можете переключать логическое значение, просто передав его, так как невозможно передать примитивы по ссылке в Java. Вам нужно будет переназначить результат метода в вашу переменную или иначе создать класс-оболочку для логического значения.
Левит
«Очевидный путь», указанный выше, помечается SONAR с - Внутренние назначения следует избегать.
Орби
2

Если вы используете логические значения NULL и считаете их ложными, попробуйте это:

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

Если вы не обрабатываете логические значения NULL, попробуйте это:

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

Это самые чистые, потому что они показывают намерение в сигнатуре метода, их легче читать по сравнению с ! оператор, и может быть легко отлажен.

использование

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

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

Конечно, если вы используете Groovy или язык, который допускает методы расширения, вы можете зарегистрировать расширение и просто сделать:

Boolean b = false
b = b.toggle() // == true
Стивен Спунгин
источник
Хороший подход, но не совсем однозначный (имхо). Для тех, кто использует / чтение, просто «toggle (..)» может подумать, что вызов метода (без повторного присвоения его переменной) может уже переключить базовую переменную. Сейчас для нас очевидно, что мы видим код, но в реальной жизни отладка может быть довольно сложной. Лучшее имя метода может быть «противоположным» или, возможно, «отрицанием», чтобы сделать это несколько более очевидным; или используйте первый подход с объектом Booleanи действительно переключайте его в методе (но все еще несколько двусмысленно).
Левит
2

Этот ответ возник при поиске «булевой функции Java Invert Boolean». Приведенный ниже пример предотвратит сбой сборок некоторыми инструментами статического анализа из-за логики ветвления. Это полезно, если вам нужно инвертировать логическое значение и не создавать комплексные модульные тесты;)

Boolean.valueOf(aBool).equals(false)

или альтернативно:

Boolean.FALSE.equals(aBool)

или

Boolean.FALSE::equals
Доктор Параметр
источник
1
Мне нравится тот факт, что вы можете перейти Boolean.FALSE::equalsк картографической функции вместо того, чтобы написать небольшую лямбду
Патрик Паркер
0

Если вы не занимаетесь чем-то особенно профессиональным, вы всегда можете использовать класс Util. Например, класс утилит из проекта для класса.

public class Util {


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

}

затем просто создайте объект Util Util u = new Util(); и получите что-то для возвратаSystem.out.println( u.flip(bool) );

Если вы собираетесь использовать одно и то же снова и снова, используйте метод, и особенно если он используется в разных проектах, создайте класс Util. Не знаю, что такое отраслевой стандарт. (Опытные программисты не стесняются меня поправлять)

Уилл Д.
источник
0

Класс BooleanUtilsподдерживает отрицание логического значения. Вы найдете этот класс в Commons-Lang: Commons-Lang

BooleanUtils.negate(theBoolean)
Alex
источник
-4

Перед:

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

После:

boolean result = isresult();
result ^= true;
Нихил Кумар
источник
Кто нибудь голосовал? Не могли бы вы также объяснить причину?
Нихил Кумар
11
Я могу подумать о двух основных причинах, по которым кто-то мог отказать вам в голосовании: 1) Некромантия темы ( давай! Вопрос был задан 7 (!) Лет назад! ), И ваш ответ не принес ничего нового в таблицу; 2) избиратель ожидал чего-то «чище» ( читай: короче ) - ответ Аарона Маенпаа - яркий тому пример.
Прииду Нимре
5
@Elltz: Наоборот - я фактически проголосовал за него, так как ответ был технически правильным. Однако я должен сказать, что мне не нравится тенденция бутлегерства ответов предыдущих пользователей для дешевой кармы (см. Ответ nlaq).
Прииду Нимре
@PriiduNeemre, вопрос задан и ответ принят до 7+ лет, и вы думаете, кроме вашего списка, кто-нибудь откажется от голосования? кроме этого ваш ответ также не на
должном уровне
2
после: логический результат =! isresult ();
Петтер Фриберг