Создание логического исключающего ИЛИ в Java

Наблюдения:

В Java есть логический оператор И.
В Java есть логический оператор ИЛИ.
В Java есть логический оператор НЕ.

Проблема:

В Java нет логического оператора XOR, согласно Sun. Я хотел бы дать определение одному.

Определение метода:

Как метод это просто определяется следующим образом:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}


Вызов метода:

Этот метод вызывается следующим образом:

boolean myVal = logicalXOR(x, y);


Использование оператора:

Я бы предпочел, чтобы оператор использовался следующим образом:

boolean myVal = x ^^ y;


Вопрос:

Я не могу найти ничего о том, как определить новый оператор в Java. С чего мне начать?


person eleven81    schedule 07.04.2009    source источник
comment
какие? ссылка, которую вы указали, содержит "побитовое исключающее ИЛИ"   -  person Mathew P. Jones    schedule 10.03.2015
comment
Вам было интересно, можно ли определять операторы в Java, как в C ++?   -  person avgvstvs    schedule 28.05.2015
comment
Похоже, вы неправильно поняли разницу между & и &&. Оба являются логическими операторами (с логическим значением). Ответ Starblue охватывает это более широко.   -  person Vlasec    schedule 04.08.2016
comment
то, что его нет в учебнике, не означает, что в Java его нет - учебные пособия (не всегда) являются полными. См. Спецификацию языка Java 15.22.2   -  person user85421    schedule 19.08.2016
comment
Он называется !=, есть также логический XNOR под названием ==.   -  person Mark K Cowan    schedule 12.03.2018


Ответы (19)


В Java есть логический оператор XOR, это ^ (как в a ^ b).

Кроме того, в Java нельзя определять новые операторы.

Изменить: Вот пример:

public static void main(String[] args) {
    boolean[] all = { false, true };
    for (boolean a : all) {
        for (boolean b: all) {
            boolean c = a ^ b;
            System.out.println(a + " ^ " + b + " = " + c);
        }
    }
}

Выход:

false ^ false = false
false ^ true = true
true ^ false = true
true ^ true = false
person javashlook    schedule 07.04.2009
comment
Это тоже ускользнуло от моей памяти, когда я писал свой пост, но я думаю, вы МОЖЕТЕ использовать ^ как логический оператор (а также побитовый). - person Neil Coffey; 07.04.2009
comment
^ - это не только побитовый оператор. Это также логический оператор. Оператор ^ перегружен. Он работает с целочисленными типами или логическими типами. +1 за отличный ответ javashlook. Эдди, это не может быть более явным, чем раздел 15.22.2 JLS, Булевы логические операторы &, ^ и |. - person erickson; 07.04.2009
comment
@mmyers: Посмотрите ссылку, в которой только что отредактировал OP. Sun в книге «Изучение языка Java» перечисляет логическое ИЛИ, побитовое ИЛИ, побитовое исключающее ИЛИ и т. д., но без логического XOR. Фактически, да, он есть. Но это непоследовательно. Почему у нас есть && и || но не ^^, а &, |, ^ можно использовать таким же образом - person Eddie; 07.04.2009
comment
И, конечно же, ответ таков: && и || пропустит вычисление второй части выражения, а & и | всегда будет оценивать обе части выражения (из моего чтения JLS). A ^^ всегда должен оценивать обе части по определению, поэтому ведет себя идентично ^. Наверное, почему нет ^^ - person Eddie; 07.04.2009
comment
@Eddie: Это и ^^ слишком похоже на смайлик. - person Michael Myers; 07.04.2009
comment
Может быть, дело в семантике, но когда дело доходит до XOR, побитовые и логические операции дают один и тот же результат. Следовательно, нет необходимости в отдельных операторах. Упрощенная таблица истинности для оператора XOR - X ^! X = 1. Вы не можете закоротить вход в XOR, потому что вы должны определить, являются ли входы разными. Это намного легче понять, если вы знаете, как изготовлен фактический вентиль XOR. - person hfontanez; 09.04.2015
comment
Единственная причина использовать & или | как логический оператор, о котором я могу думать, это оценивать обе стороны, когда у них есть какие-то желательные побочные эффекты. Это приводит к тому, что люди игнорируют их (как логические операторы) до такой степени, что новички даже не подозревают, что они вообще являются логическими операторами. - person Vlasec; 04.08.2016
comment
Я бы сказал, что && - нормальный вариант для большинства людей - person Mark; 15.03.2019
comment
Кстати: это можно было бы пополнить простым a != b - person Grigory Kislin; 28.06.2019

Разве это не х! = У?

person Maurice Perry    schedule 07.04.2009
comment
Если x и y являются логическими, то логическая таблица для xor и! = Идентична: t, t = ›f; t, f = ›t; f, t = ›t; f, f = ›f - person Greg Case; 07.04.2009
comment
Морис: А, ты просто взорвал мне голову! Как я этого не замечал? - person ; 07.04.2009
comment
Ух ты! это был спорный вопрос! Я думаю, что ^ - лучший ответ, если вас интересует логическая арифметика, и этот вариант лучше, если вы просто хотите сравнить два логических значения. - person Maurice Perry; 07.04.2009
comment
@Milhous Вы хотите сказать, что a != b != c не будет работать, а a ^ b ^ c будет? В этом случае, вы ошибаетесь. - person fredoverflow; 01.03.2014
comment
Морис, просто молодец! Бывает, что я упускаю простые вещи из виду, когда есть много дел :) - person sberezin; 09.09.2014
comment
@Milhous Чего ты ждёшь от a ^ b ^ ... ^ z? Если вы хотите получить истинный результат только тогда, когда одна из переменных истинна, вы будете очень разочарованы. Обе цепочки из ^ и != возвращают истину, если количество истинных переменных нечетное. Что нужно иметь в виду. - person Tobia; 17.03.2015
comment
Как и != для XOR, вы получите == для XNOR. К сожалению, для NAND и NOR нет встроенных символов. !& и !| было бы круто. - person Tobia; 17.03.2015
comment
Это небезопасный тип - person ZhekaKozlov; 22.11.2016
comment
Этот подход не работает, когда обе стороны являются классами-оболочками, new Boolean(true) != new Boolean(true) дает true. - person Vlastimil Ovčáčík; 21.01.2017
comment
@ VlastimilOvčáčík А как там альтернативный оператор ^? Думаю, он тоже взрывается ... - person Stijn de Witt; 05.06.2017
comment
@StijndeWitt нет, это не так: ^ не применяется к объектам, тогда как! = Применяется. - person Maurice Perry; 06.06.2017
comment
Я предпочитаю это решение из-за удобочитаемости. ^ очень-очень редко. - person Balázs Németh; 30.09.2019
comment
@ VlastimilOvčáčík - вот почему вы никогда не используете new Boolean. Этот конструктор (как и большинство конструкторов) не должен был быть публичным. Используйте Boolean.valueOf. - person Doradus; 30.01.2020
comment
что черт возьми? мой Бог ?? это реально? - person snr; 03.12.2020

В Java есть логический оператор И.
В Java есть логический оператор ИЛИ.

Неправильный.

Java имеет

  • два логических оператора И: обычное И - это &, короткое И - это &&, и
  • два логических оператора ИЛИ: нормальное ИЛИ равно | и ИЛИ короткого замыкания ||.

XOR существует только как ^, потому что оценка короткого замыкания невозможна.

person starblue    schedule 07.04.2009
comment
Интересный комментарий. Это задокументировано? - person user666412; 28.03.2013
comment
Я думаю & и | не являются короткозамкнутыми, поскольку являются побитовыми операторами. А на самом деле замкнуть их накоротко не возможно. - person Krzysztof Jabłoński; 14.05.2013
comment
@Krzysztof Jabłoński Это побитовые операторы над числами, но здесь мы говорим о логических выражениях. - person starblue; 15.05.2013
comment
@ user666412 Да, в спецификации языка Java (где еще?). - person starblue; 15.05.2013
comment
Если он имеет 2 оператора И и 2 оператора ИЛИ, тогда утверждения «Java имеет логический оператор И» и «Java имеет логический оператор ИЛИ» не являются неправильными. По определению, если у вас есть 2 штуки, значит, у вас также есть 1 штука. - person RyanfaeScotland; 20.05.2013
comment
@RyanfaeScotland Не принимайте это слишком серьезно, я просто хотел донести суть. Что на самом деле неправильно (а также неправильно в учебнике Sun), так это то, что в Java нет оператора XOR. - person starblue; 25.02.2016
comment
Ничего не могу поделать, но серьезно относитесь к тому, когда кто-то отвечает односложным предложением! - person RyanfaeScotland; 25.02.2016
comment
Для наглядности символы &, ^ и | перегружены как побитовые операторы (см. JLS 15.22.1) и логических логических операторов (см. JLS 15.22.2). && и || являются логическими операторами условного И и ИЛИ (JLS 15.23 и 15.24.), поддерживающие короткое замыкание; условной побитовой версии нет. - person Pixelstix; 05.12.2016

Возможно, вы неправильно поняли разницу между & и &&, | и || Назначение операторов быстрого доступа && и || состоит в том, что значение первого операнда может определять результат, поэтому второй операнд не нуждается в оценке.

Это особенно полезно, если второй операнд приведет к ошибке. например

if (set == null || set.isEmpty())
// or
if (list != null && list.size() > 0)

Однако при использовании XOR вы всегда должны оценивать второй операнд, чтобы получить результат, поэтому единственной значимой операцией является ^.

person Peter Lawrey    schedule 07.04.2009

Вы можете просто написать (a!=b)

Это будет работать так же, как a ^ b.

person Shuliyey    schedule 04.06.2013

Это потому, что перегрузка операторов - это то, что они специально исключили из языка. Они немного «схитрили» с конкатенацией строк, но кроме этого, такой функциональности не существует.

(отказ от ответственности: я не работал с двумя последними основными выпусками java, поэтому, если он сейчас доступен, я буду очень удивлен)

person Kevin Anderson    schedule 07.04.2009
comment
Имейте в виду, что вы также не можете определять новые операторы в C ++. Все, что вы можете сделать, это придать новый смысл старому. - person David Thornley; 08.04.2009

Единственная перегрузка оператора в Java - это + для строк (JLS 15.18.1 Оператор конкатенации строк +).

Сообщество было разделено на 3 года, 1/3 этого не хочет, 1/3 этого хочет, а 1/3 все равно.

Вы можете использовать Unicode для создания имен методов, которые являются символами ... поэтому, если у вас есть символ, который вы хотите использовать, вы можете сделать myVal = x. $ (Y); где $ - это символ, а x - не примитив ... но в некоторых редакторах это будет изворотливым и ограничивающим, поскольку вы не можете сделать это в примитиве.

person TofuBeer    schedule 07.04.2009

Следующий ваш код:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

лишнее.

Почему бы не написать:

public static boolean logicalXOR(boolean x, boolean y) {
    return x != y;
}

?

Кроме того, как сказал javashlook, уже есть оператор ^.

!= и ^ работают одинаково * для логических операндов (ваш случай), но по-разному для целочисленных операндов.

* Примечания:
1. Они работают одинаково для boolean (примитивный тип), но не Boolean (тип объекта) операндов. Поскольку значения Boolean (тип объекта) могут иметь значение null. И != вернет false или true, когда один или оба его операнда равны null, а ^ в этом случае выдаст NullPointerException.
2. Хотя они работают одинаково, у них разный приоритет, например при использовании с &: a & b != c & d будет рассматриваться как a & (b != c) & d, а a & b ^ c & d будет рассматриваться как (a & b) ^ (c & d) (оффтоп: ой, таблица приоритетов в стиле C - отстой).

person Sasha    schedule 13.04.2016
comment
Для логических значений мне нравится != - person GKalnytskyi; 13.05.2016
comment
@GKalnytskyi для Boolean значений != работает некорректно. Для значений boolean это нормально. - person vadipp; 27.06.2017
comment
! = и ^ не работают одинаково для логических операндов. Вы получите разные результаты для false & false! = True и false & false ^ true из-за приоритета. - person Albert Hendriks; 17.12.2017
comment
@AlbertHendriks, я бы лучше сказал, что они работают одинаково, но имеют разный приоритет (хотя это всего лишь вопрос терминологии). - person Sasha; 17.12.2017

Вот метод var arg XOR для java ...

public static boolean XOR(boolean... args) {
  boolean r = false;
  for (boolean b : args) {
    r = r ^ b;
  }
  return r;
}

Наслаждаться

person Timothy Jacobsen    schedule 28.11.2012
comment
Похоже, он будет вести себя очень странно. Например. XOR(true,true,true) возвращает истину, что не похоже на то, что вы ожидаете от метода с именем XOR. Мое ожидаемое поведение будет заключаться в том, что он всегда возвращает false (что, конечно, бесполезно) - person Richard Tingle; 20.10.2018

Логическое исключающее ИЛИ в Java называется !=. Вы также можете использовать ^, если хотите запутать своих друзей.

person Doradus    schedule 04.04.2018

Для перегрузки операторов и 'остаться' на Яве

person iga    schedule 24.10.2012
comment
Обратите внимание, что Xtend не позволяет вам переопределить курсор ^; вы должны использовать bool_1.xor(bool_2). Как ни странно, синтаксический анализатор даже не позволяет вам использовать курсор; вы должны использовать xor для логических значений и bitwiseXor для целых чисел. Вы, конечно, можете перегрузить другого оператора, но это сильно запутает. - person Kelvin; 20.06.2016

То, о чем вы просите, не имеет большого смысла. Если я не ошибаюсь, вы предлагаете использовать XOR для выполнения логических операций таким же образом, как AND и OR. Предоставленный вами код действительно показывает, о чем я говорю:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

Ваша функция имеет логические входы, и когда побитовое XOR используется с логическими значениями, результат будет таким же, как и в коде, который вы предоставили. Другими словами, побитовое исключающее ИЛИ уже эффективно при сравнении отдельных битов (логических значений) или сравнении отдельных битов с большими значениями. Чтобы поместить это в контекст, с точки зрения двоичных значений любое ненулевое значение является ИСТИННЫМ, и только НОЛЬ является ложным.

Таким образом, чтобы XOR применялся так же, как применяется логическое И, вы должны либо использовать только двоичные значения с одним битом (что дает тот же результат и эффективность), либо двоичное значение должно оцениваться в целом, а не на бит. Другими словами, выражение (010 ^^ 110) = FALSE вместо (010 ^^ 110) = 100. Это приведет к удалению большей части семантического значения операции и представляет собой логический тест, который вы в любом случае не должны использовать.

person user2904660    schedule 25.10.2016

A и B должны быть логическими значениями, чтобы сделать! = Таким же, как xor, чтобы таблица истинности выглядела так же. Вы также можете использовать! (A == B) lol.

person John Theibert    schedule 06.06.2017

Я использую очень популярный класс org.apache.commons.lang.BooleanUtils

Этот метод проверен многими пользователями и безопасен. Повеселись. Использование:

boolean result =BooleanUtils.xor(new boolean[]{true,false});
person Adam111p    schedule 04.08.2017

Это пример использования XOR (^) из этого ответа

byte[] array_1 = new byte[] { 1, 0, 1, 0, 1, 1 };
byte[] array_2 = new byte[] { 1, 0, 0, 1, 0, 1 };

byte[] array_3 = new byte[6];

int i = 0;
for (byte b : array_1)
    array_3[i] = b ^ array_2[i++];

Выход

0 0 1 1 1 0
person Asyraf    schedule 21.12.2020

Поскольку логический тип данных хранится как целое число, битовый оператор ^ работает как операция XOR, если используется с логическими значениями.

//©Mfpl - XOR_Test.java

    public class XOR_Test {
        public static void main (String args[]) {
            boolean a,b;

            a=false; b=false;
            System.out.println("a=false; b=false;  ->  " + (a^b));

            a=false; b=true;
            System.out.println("a=false; b=true;  ->  " + (a^b));

            a=true;  b=false;
            System.out.println("a=true;  b=false;  ->  " + (a^b));

            a=true; b=true;
            System.out.println("a=true; b=true;  ->  " + (a^b));

            /*  output of this program:
                    a=false; b=false;  ->  false
                    a=false; b=true;  ->  true
                    a=true;  b=false;  ->  true
                    a=true; b=true;  ->  false
            */
        }
    }
person Ledón    schedule 09.03.2015

Вот пример:

Учитывая 2 значения типа int, верните true, если одно отрицательное, а второе положительное. За исключением случаев, когда параметр «негативный» имеет значение «истина», возвращать значение «истина» только в том случае, если оба значения отрицательны.

    public boolean posNeg(int a, int b, boolean negative) {
      if(!negative){
        return (a>0 && b<0)^(b>0 && a<0);
      }
      else return (a<0 && b<0);
    }
person SpicyCatGames    schedule 21.10.2016

вам нужно будет переключиться на Scala, чтобы реализовать свои собственные операторы

пример трубы

person mut1na    schedule 20.10.2017

Может быть достигнуто с помощью потокового API в java 8 и выше.

public static boolean logicalXOR(boolean x, boolean y) {  // can modify to take [] or list of bools
    return Stream.of(x, y)  // modify as per method params
        .filter(bool -> bool)
        .count() == 1;
}
person Harsh Gundecha    schedule 23.05.2021