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

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

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

person Kevin Griffin    schedule 22.10.2008    source источник
comment
о, хорошо, я собирался задать тот же вопрос, хотя мой вопрос был бы специфическим для javascript / as3 или ECMAScript в целом, я полагаю ... который легко будет охвачен этим вопросом.   -  person matt lohkamp    schedule 07.01.2009
comment
Что делать, если нет! оператор ??   -  person onmyway133    schedule 12.09.2014


Ответы (9)


theBoolean ^= true;

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

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

person Community    schedule 22.10.2008
comment
Краткость - это душа остроумия. - person Paul Brinkley; 23.10.2008
comment
Теперь я могу небрежно отбрасывать имя (синтаксис?) XOR, чтобы круто выглядеть перед моими друзьями-программистами. Ваш ответ должен сливаться с избранным, вместе они чистое совершенство. - person matt lohkamp; 07.01.2009
comment
@ScottStanchfield Такие люди должны этому научиться. Это совсем несложно, это не взлом, и незнание этого часто приводит к дрянному коду, например один этот вопрос. Это настоящий прорыв - пять строк в стандартных условных обозначениях! - person maaartinus; 21.06.2014
comment
Подумайте о том, следует научиться этому, а не пытаться понять, что происходит, когда у вас есть день, чтобы исправить ошибку. Да, XOR здесь круто, но сколько людей, которым я упомянул XOR, сказали, да? потрясающе. Вы всегда должны писать код для обслуживающего программиста, максимально упрощая его работу, потому что независимо от того, насколько хорошо написан код, чтение чужого кода действительно отстой. - person Scott Stanchfield; 25.06.2014
comment
Но ... это позволяет параметризовать отрицание :) theBoolean ^= shouldBeNegated; - person estani; 03.07.2014
comment
Эта операция также на 12% быстрее, чем другие версии, такие как theBoolean = !theBoolean; или theBoolean = theBoolean ? false : true; - person Blaine Kasten; 28.07.2014
comment
@BlaineKasten, по-видимому, больше нет. Все работает с одинаковой скоростью (FF43, 64-разрядная версия Ubuntu 15) РЕДАКТИРОВАТЬ: Это на 50% медленнее для меня в Chrome 47, в то время как троичный имеет скорость бесконечности. - person Florian Wendelborn; 11.01.2016
comment
Если вы объявляете логическую константу со значением true в классе T и называете ее t, вы можете сохранить одно дополнительное нажатие клавиши: myVal ^= T.t;. Не говоря уже о статическом импорте ... _5 _... Безлимитный пух! - person Timmos; 21.04.2016
comment
@BlaineKasten - В Chrome 55 на OS X это самый медленный результат на 53%. Интересно, что троичное выражение является самым быстрым. - person Ted Hopp; 27.01.2017

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

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

theBoolean = !theBoolean;

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

theBoolean ^= true;

Самый "наглядный" способ (наиболее неопределенно)

theBoolean = theBoolean ? false : true;

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

theMethod( theBoolean ^= true );

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

person Levite    schedule 14.11.2016
comment
Оберните реализацию в функцию / метод под названием toggle, и тогда почти не будет способа запутать его. - person Lambage; 08.09.2017
comment
@Reiner: Для C определенно, но в Java нельзя смешивать логические и целые числа (в Java также нельзя использовать такие вещи, как while(1)). - person Levite; 05.04.2018
comment
@Lambage: Верно, но с другой стороны, вы не можете переключить логическое значение, просто передав его, поскольку в Java невозможно передавать примитивы по ссылке. Вам придется переназначить результат метода вашей переменной или иным образом создать класс-оболочку для логического значения. - person Levite; 05.04.2018
comment
Очевидный способ выше помечен SONAR с помощью - Следует избегать внутренних назначений. - person Orby; 11.04.2018

Этот ответ возник при поиске «java invert boolean function». В приведенном ниже примере предотвращается сбой сборки некоторых инструментов статического анализа из-за логики ветвления. Это полезно, если вам нужно инвертировать логическое значение и вы не создали исчерпывающих модульных тестов;)

Boolean.valueOf(aBool).equals(false)

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

Boolean.FALSE.equals(aBool)

or

Boolean.FALSE::equals
person Doctor Parameter    schedule 16.08.2019
comment
Мне нравится, что вы можете передать Boolean.FALSE::equals функции сопоставления вместо того, чтобы писать небольшую лямбду. - person Patrick Parker; 11.11.2019

Если вы используете логические значения 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
person Steven Spungin    schedule 01.07.2017
comment
Хороший подход, но не совсем однозначный (имхо). Кто-то, кто использует / читает просто toggle (..), может подумать, что вызов метода (без повторного присвоения его переменной) может уже переключить базовую переменную. Сейчас для нас очевидно, что мы видим код, но в реальной жизни может быть довольно сложно отладить. Лучшее имя метода может быть противоположным или, возможно, отрицательным, чтобы сделать это более очевидным; или используйте первый подход с объектом Boolean и действительно переключите его внутри метода (но все же несколько неоднозначно). - person Levite; 01.02.2019

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

BooleanUtils.negate(theBoolean)
person Alex    schedule 04.06.2020

Если вы не делаете ничего особенно профессионального, вы всегда можете использовать класс 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. Однако не знаю, что такое отраслевой стандарт. (Опытные программисты меня поправляют)

person Will D.    schedule 11.04.2019
comment
Проголосовали против. 1. Это не улучшает читаемость. 2. Это добавляет серьезные накладные расходы времени выполнения. 3. Утильные классы обычно представляют собой запах кода. - person rds; 13.03.2021

К сожалению, нет краткой формы, например, у чисел есть увеличение / уменьшение:

i++;

Я хотел бы иметь аналогичное короткое выражение для инвертирования логического значения dmth, например:

пустой!;

person Denys    schedule 05.08.2020
comment
Не уверен, почему вы говорите это, когда на этот вопрос был дан ответ в этой беседе двенадцать лет назад. - person Luke Perez; 14.10.2020

До:

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

После:

boolean result = isresult();
result ^= true;
person Nikhil Kumar    schedule 02.04.2015
comment
Кто хоть раз голосовал против? Не могли бы вы также объяснить причину? - person Nikhil Kumar; 15.04.2015
comment
Я могу придумать две основные причины, по которым кто-то мог проголосовать против вас: 1) Некромантия темы (да ладно! Вопрос был задан 7 (!) Лет назад!) и ваш ответ не приносит ничего нового к столу; 2) Избиратель ожидал чего-то более чистого (читай: короче) - ответ Аарона Маенпаа является ярким примером этого. - person Priidu Neemre; 30.04.2015
comment
@Elltz: Напротив - я фактически поддержал его, поскольку ответ был технически правильным. Однако я должен сказать, что мне не нравится тенденция бутлегерства ответов предыдущих пользователей на дешевую карму (см. Ответ nlaq). - person Priidu Neemre; 09.06.2015
comment
@PriiduNeemre, заданный вопрос и ответ принят до 7+ лет, и как вы думаете, кроме вашего списка, кто-нибудь отдаст свой голос? кроме этого ваш ответ тоже не на высоте .. :( - person user1140237; 11.01.2016
comment
после: логический результат =! isresult (); - person Petter Friberg; 14.04.2016

person    schedule
comment
Это ... действительно очевидно - ой! Не знаю, почему я не подумал об этом. Спасибо. - person Kevin Griffin; 22.10.2008
comment
! Логическое значение кажется естественным выбором - возможно, в будущем. - person matt lohkamp; 07.01.2009
comment
@ypnos: !!bool == !(!(bool)) == bool. - person Christoffer Hammarström; 21.07.2011
comment
@ ChristofferHammarström По этой логике, тогда не должно быть --integer == - (- (integer)) == integer? - person user515655; 11.12.2015
comment
@ user515655 - Язык определяет оператор -- (фактически, два из них вместе с двумя операторами ++), но не определяет оператор !!. Если вы хотите -(-(integer)), вы можете использовать пробел между двумя символами -. Но !! анализирует как два ! оператора независимо от пробелов. - person Ted Hopp; 27.01.2017
comment
В таком случае, как насчет bool!! - person mid; 19.07.2017