Создание «логического исключающего или» оператора в Java - PullRequest
257 голосов
/ 07 апреля 2009

Замечания:

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

Проблема:

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

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

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

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


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

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

boolean myVal = logicalXOR(x, y);


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

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

boolean myVal = x ^^ y;


Вопрос:

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

Ответы [ 17 ]

655 голосов
/ 07 апреля 2009

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
294 голосов
/ 07 апреля 2009

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

71 голосов
/ 07 апреля 2009

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

Неправильно.

Java имеет

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

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

31 голосов
/ 08 апреля 2009

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

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

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

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

20 голосов
/ 04 июня 2013

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

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

9 голосов
/ 07 апреля 2009

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

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

7 голосов
/ 13 апреля 2016

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

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) (offtopic: ой, таблица приоритетов в стиле C не работает).

7 голосов
/ 07 апреля 2009

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

Сообщество делится на 3 года, 1/3 не хочет, 1/3 хочет, а 1/3 не волнует.

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

6 голосов
/ 29 ноября 2012

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

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

Наслаждайтесь

2 голосов
/ 26 октября 2016

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

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

Ваша функция имеет логические входы, и при использовании побитового XOR для логических значений результат будет таким же, как и код, который вы предоставили. Другими словами, побитовое XOR уже эффективно при сравнении отдельных битов (логических значений) или при сравнении отдельных битов в больших значениях. Чтобы поместить это в контекст, в терминах двоичных значений любое ненулевое значение равно TRUE, и только ZERO - false.

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

...