Створення оператора "логічний ексклюзив" або "Java"


274

Спостереження:

У Java є логічний оператор І.
У Java є логічний оператор АБО.
У Java є логічний оператор НЕ.

Проблема:

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. З чого слід почати?


1
що? посилання, яке ви надали, містить вміст "побітовий ексклюзивний АБО"
Меттью П. Джонс

Вам було цікаво, чи зможете ви визначити операторів на Java, як ви можете в C ++?
avgvstvs

1
Здається, ви неправильно зрозуміли різницю між & і &&. Обидва є логічними операторами (на булевому рівні). Відповідь Starblue охоплює це ширше.
Власек

тільки те, що його немає в підручнику , не означає, що у Java його немає - підручники не є (завжди) повними. Див. Специфікацію мови Java 15.22.2
user85421

5
Це називається !=, також є логічний XNOR під назвою==
Марк К Коуан

Відповіді:


695

У 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 ^ true = правда
true ^ false = правда
true ^ true = хибно

5
Це також уникнуло моєї пам’яті, коли я писав свій пост, але я думаю, що ви МОЖЕТЕ використовувати ^ як логічний оператор (як і бітовий).
Ніл Коффі

144
^ - не лише побітовий оператор. Це також логічний оператор. Оператор ^ перевантажений. Він працює на інтегральних типах або булевих типах. +1 за відмінну відповідь javashlook. Едді, це не стає більш явним, ніж розділ 15.22.2 JLS, "Логічні оператори логіки &, ^ і |".
erickson

97
І звичайно, відповідь полягає в тому, що && і || пропустить оцінку 2-ї частини виразу та & і | завжди буде оцінювати обидві частини виразу (з мого читання JLS). A ^^ завжди повинен був би оцінювати обидві частини, за визначенням, тому поводиться ідентично ^. Можливо, тому немає ^^
Едді

81
@Eddie: Це і ^^ просто дуже схоже на смайлик.
Майкл Майєрс

5
Можливо, справа в семантиці, але коли мова заходить про XOR, побітові та логічні результати дають той же результат. Тому немає необхідності у чітких операторах. Спрощена таблиця істинності для оператора XOR - X ^! X = 1. Ви не можете коротко замикати вхід у XOR, оскільки вам потрібно визначити, чи різні входи. Це набагато простіше зрозуміти, якщо ти знаєш виготовлення власне ворота XOR.
hfontanez

305

Хіба це не х! = У?


5
Якщо x і y булеві, то логічна таблиця для xor і! = Однакова: t, t => f; t, f => t; f, t => t; f, f => f
Справа Грега

81
Моріс: Арр, ти щойно підірвав мій розум! Як я ніколи цього не помічав?

8
@Milhous Ти кажеш a != b != c, не буде працювати, але a ^ b ^ cбуде? У такому випадку ви помиляєтесь .
fredoverflow

3
Моріс, просто геніальний! Мені трапляється втрачати прості речі з поля зору, коли багато чого робити :)
sberezin

6
Це схвалення накладається, коли обидві сторони є класами обгортки, new Boolean(true) != new Boolean(true)дає true.
Властиміл Овчачик

74

У Java є логічний оператор І.
У Java є логічний оператор АБО.

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

Java має

  • два логічних оператора AND: нормальний AND є &, а коротке замикання AND - &&, і
  • два логічні оператори АБО: нормальне АБО є | а коротке замикання АБО ||.

XOR існує лише як ^, оскільки оцінка короткого замикання неможлива.


2
Цікавий коментар. Це документально підтверджено?
користувач666412

1
Я думаю & і | не є коротким замиканням, оскільки вони є бітовими операторами. А насправді їх коротке замикання неможливо.
Кшиштоф Яблонський

3
@Krzysztof Jabłoński Вони є побітними операторами чисел, але тут ми говоримо про булеві вирази.
starblue

3
@ user666412 Так, у специфікації мови Java (де ще?).
starblue

18
Якщо у нього є 2 операторів AND і 2 OR операторів, то твердження "Java має логічний AND оператор", а "Java має логічний оператор АБО" не є помилковим. За визначенням, якщо у вас є щось із чогось, то ви також маєте 1 це.
RyanfaeScotland

31

Можливо, ви неправильно зрозуміли різницю між &і &&, |і || Ціл операторів швидкого доступу, &&і в ||тому, що значення першого операнда може визначати результат, і тому другий операнд не потрібно оцінювати.

Це особливо корисно, якщо другий операнд призведе до помилки. напр

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

Однак з XOR завжди потрібно оцінювати другий операнд, щоб отримати результат, тому єдиною значущою операцією є ^.


20

Можна просто написати (a!=b)

Це буде працювати так само, як і a ^ b.


9

Це тому, що перевантаження операторів - це те, що вони спеціально лишилися поза мовою. Вони трохи "обдурили" стрункову конкатенацію, але поза цим такої функціональності не існує.

(відмова від відповідальності: я не працював з останніми двома основними випусками Java, тому, якщо це вже зараз, я буду дуже здивований)


5
Майте на увазі, що ви також не можете визначити нових операторів у C ++. Все, що ви можете зробити - це дати новим значенням старим.
Девід Торнлі

7

Єдиний оператор, який перевантажує Java, є + на Strings ( JLS 15.18.1 String Concatenation Operator + ).

Спільнота поділяється на 3 роки, 1/3 не хоче, 1/3 хоче, а 1/3 не хвилює.

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


7

Наступний ваш код:

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: ouch, стійка таблиці пріоритетів у стилі C).


1
За булеві значення мені подобається!=
Г.Кальницький

1
@GKalnytskyi для Booleanзначень !=працює неправильно. Для booleanзначень це нормально.
vadipp

2
! = і ^ не працюють однаково для булевих операндів. Ви отримаєте різні результати для "false & false! = True" порівняно з "false & false ^ true" через перевагу.
Альберт Гендрікс

1
@AlbertHendriks, я краще скажу, що вони працюють однаково, але мають різний пріоритет (хоча це лише питання термінології).
Сашко

6

Ось метод var arg XOR для Java ...

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

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


Це здається, що його матиме дуже дивна поведінка. Наприклад, XOR(true,true,true)повертається true, що здається не схожим на те, що ви очікували від названого методу XOR. Моєю очікуваною поведінкою було б те, що вона завжди повертається помилково (що, звичайно, не корисно)
Річард Тінгл

4

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


2

Ви можете використовувати Xtend (оператори інфікування та перевантаження оператора) для перевантаження операторів та «перебування» на Java


Зауважте, що Xtend не дозволяє вам переосмислити каре ^; ви повинні використовувати bool_1.xor(bool_2). Як не дивно, аналізатор навіть не дозволяє використовувати каре; ви повинні використовувати xorдля булевих і bitwiseXorцілих чисел. Можна, звичайно, перевантажити іншого оператора, але це стане дуже заплутаним.
Келвін

2

Те, про що ви просите, не мало б великого сенсу. Якщо я невірний, ви пропонуєте використовувати XOR для виконання логічних операцій так само, як і AND і OR. Наданий код насправді показує, на що я звертаюсь:

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

У вашій функції є булеві входи, і коли бітовий XOR використовується на булевих результатах, результат такий же, як і код, який ви вказали. Іншими словами, побітовий XOR вже ефективний при порівнянні окремих бітів (булевих) або порівнянні окремих бітів у більших значеннях. Щоб поставити це в контекст, з точки зору бінарних значень будь-яке ненульове значення є ПРАВИЛЬНИМ, і лише ZERO - хибним.

Отже, щоб XOR застосовувався так само, як застосовується логічний AND, ви використовуєте лише бінарні значення лише з одним бітом (даючи однаковий результат та ефективність), або двійкове значення має оцінюватися як ціле, а не за біт. Іншими словами, вираз (010 ^^ 110) = FALSE замість (010 ^^ 110) = 100. Це видалить більшу частину смислового значення з операції і являє собою логічний тест, який ви не повинні використовувати.


1

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


1

Я використовую дуже популярний клас "org.apache.commons.lang.BooleanUtils"

Цей метод перевірений багатьма користувачами і безпечний. Весело. Використання:

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

0

Оскільки булевий тип даних зберігається як ціле число, бітовий оператор ^ функціонує як операція 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
            */
        }
    }

0

Ось приклад:

З урахуванням 2-х значень int, поверніть істинне, якщо одне є негативним, а одне - позитивним. За винятком випадків, коли параметр "негативний" є істинним, повертайте істинне, лише якщо обидва є негативними.

    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);
    }

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.