Укороченные логические операторы java

&& и || и их братья & и | в разных ситуациях. Какие у них различия?

друзья! Хотелось бы спросить про && и ||. Если используется двойной амперсанд и первое выражение ложно (false), то второе выражение даже не будет проверяться, т.к. вне зависимости от него,всё выражение будет ложным. При одном амперсанде будут вычислены оба условия. Всё понятно, но есть ли смысл иметь в ЯП двойной амперсанд? Посмотрел, поиспользовал,честно не понял зачем их 2 придумали. Все мои результаты как только не делал вышли одинаковыми.

 public static void main(String[] args) < int a = 2; int b = 3; int c = 4; if (a == 2 && b == 3)< System.out.println("Hello"); >else < System.err.println("Error"); >> 

Да я понимаю, что с && он проверяет первое значение и если оно false, то дальше даже не проверяет, тогда вопрос: Нужен ли в таком случае &(одинарный амперсанд)? Распишите примеры пожалуйста, где идут отличия & от && и где они могут по разному работать, потому что я увидел только одинаковую работу.

Функция помимо возвращения логического значения может ещё иметь некие побочные эффекты. Хотя, конечно, лучше так не писать.

Как я понял из трёх одинаковых ответов, двухсимвольные операторы нужны для правильных сравнений, а короткие для сомнительного кода, от которого вреда больше чем пользы. И читаться односимвольные должны так: «смотри, читатель! Тут нам мало получить результат сравнения, на самом деле писатель заложил какой-то сюрприз где-то там в глубине» .

Читайте также:  Java создать класс конструктор

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

4 ответа 4

  • Операторы | и || — это логические операторы ИЛИ . Работает так: если хотя бы одно условие true , то все результат true. Т.е., если одно условие false , а другое — true , то результат true.
  • Операторы & и && — это логические операторы И . Работает так: если хотя бы одно условие false , то результат — false . Т.е, чтобы результат был true , надо чтобы оба условия были true .

Допустим, у вас такая проверка: checkFirst() && checkSecond() .

boolean метод checkSecond() :

. System.out.println("Метод checkSecond был вызван т.к. метод checkFirst вернул true"); . 

И эта надпись может выводиться в консоль, а может и не выводиться. А если бы вы указали & , то она бы выводилась всегда, даже если бы checkFirst возвращал false . Т.е. иногда надо, чтобы проверялись оба условия, независимо от того, повлияет ли это на что-нибудь. А && было придумано для улучшения производительности, мало ли какие громоздкие проверки у вас стоят — чтобы они не выполнялись лишний раз.

P.S. Andrey NOP написал в комментариях к вопросу про побочные эффекты, println выше — это как раз побочный эффект. Вместо println может быть присваивание какого-то значения важному полю, и т.п.

public static void main(String[] args) < //тут вызовутся оба метода, т.к. checkFirst возвр. true, потом вызовется checkSecond, он тоже true, условие выполнится if (checkFirst(0) && checkSecond(0)) System.out.println("Первое условие выполнено\n"); //тут вызовется только checkFirst, т.к. checkFirst возвр. false, и уже не надо проверять checkSecond, т.к. условие ложное, оно не выполнится if (checkFirst(1) && checkSecond(0)) System.out.println("Второе условие выполнено\n"); //здесь вызовутся оба метода, т.к. это "&", и оба вернут true, условие выполнится if (checkFirst(0) & checkSecond(0)) System.out.println("Третье условие выполнено\n"); //здесь вызовутся оба метода, условие не выполнится, т.к. checkSecond возвр. false if (checkFirst(0) & checkSecond(1)) System.out.println("Четвертое условие выполнено\n"); >private static boolean checkFirst(int i) < System.out.println("Вызван checkFirst"); if (i == 0) return true; return false; >private static boolean checkSecond(int i)
Вызван checkFirst Вызван checkSecond Первое условие выполнено Вызван checkFirst Вызван checkFirst Вызван checkSecond Третье условие выполнено Вызван checkFirst Вызван checkSecond 

Источник

Логические операторы

Логические операторы языка Java выполняются только с операндами типа boolean .

Следующая таблица перечисляет логические операторы языка Java:

Операция Описание
& Логическая операция И (AND) или конъюнкция
| Логическая операция ИЛИ (OR) или дизъюнкция
^ Логическая операция исключающее ИЛИ (XOR)
! Логическая унарная операция НЕ (NOT)
|| Укороченная логическая операция ИЛИ (short-circuit)
&& Укороченная логическая операция И (short-circuit)
== Равенство
!= Неравенство
&= Логическая операция И с присваиванием
|= Логическая операция ИЛИ с присваиванием
^= Логическая операция исключающее ИЛИ с присваиванием

1. Логические операторы OR, AND, XOR, NOT.

Начнем с операций OR(|), AND(&), XOR(^), NOT(!). Операторы OR, AND, XOR являются бинарными — они требуют два оператора. NOT — это унарный оператор, только один оператор участвует в операции. Результаты выполнения этих логических операций представлены в следующей таблице:

A B A|B A&B
A^B
!A
false false false false false true
true false true false true false
false true true false true true
true true true true false false

OR (|) — результат будет true , если хотя бы одно значение равно true . Пример: для того, чтобы забрать ребенка из садика, должна прийти либо мать, либо отец, либо оба — в любом случае результат будет положительный. Если же никто не придет, ребенка не заберут — результат будет отрицательный.

AND (&) — результат будет true , только если и A, и B равны true . Пример: для того чтобы свадьба состоялась, и невеста (A) и жених (B) должны явиться на бракосочетание, иначе оно не состоится.

XOR (^) — результат будет true , только если или A равно true , или В равно true . Пример: у двух друзей на двоих один велосипед, поездка на велосипеде состоится только если один из них поедет на нем. Вдвоем они ехать не могут.

NOT (!) — инвертирование значения. Если значение было true, то станет false , и наоборот.

Рассмотрим пример использования логических операторов:

public class BooleanLogic1 < public static void main(String[] args) < boolean a = true; boolean b = false; boolean c = a | b; boolean d = a & b; boolean e = a ^ b; boolean f = (!a & b) | (a & !b); boolean g = !a; System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("a | b = " + c); System.out.println("a & b = " + d); System.out.println("a ^ b = " + e); System.out.println("(!a & b) | (a & !b) = " + f); System.out.println("!a header3">2. Укороченные логические операторы (short-circuit). 

Чаще всего в языке Java используются так называемые укороченные логические операторы (short-circuit):

|| - Укороченный логический оператор ИЛИ
&& - Укороченный логический оператор И

Правый операнд сокращенных операций вычисляется только в том случае, если от него зависит результат операции, то есть если левый операнд конъюнкции имеет значение true, или левый операнд дизъюнкции имеет значение false.

В формальной спецификации языка Java укороченные логические операции называются условными.

В следующем примере правый операнд логического выражения вычисляться не будет, так как условие d!=0 не выполняется и нет смысла дальше вычислять это выражение:

public class BooleanLogic2 < public static void main(String[] args) < int d = 0; int num = 10; if (d != 0 && num / d >10) < System.out.println("num language-java">public class BooleanLogic3 < public static void main(String[] args) < int a = 1; int b = 2; int x = 3; System.out.print(a < x && x < b); // System.out.print(a < x < b);//Ошибка компиляции >>

3. Операции ==, !=.

Здесь все просто - чтобы сравнить два значения типа boolean , можно использовать знаки == (проверка на равенство) и != (проверка на неравенство):

public class BooleanLogic4 < public static void main(String[] args) < boolean b1 = true; boolean b2 = false; System.out.println(b1 == b2); System.out.println(b1 != b2); >>

4. Операции с присваиванием.

Также существуют операции с присваиванием для AND, OR, XOR. Посмотрим пример:

public class BooleanLogic5 < public static void main(String[] args) < boolean b1 = true; boolean b2 = true; b1 &= b2;//равносильно b1 = b1 & b2; System.out.println(b1); b1 |= b2; //равносильно b1 = b1 | b2; System.out.println(b1); b1 ^= b2; //равносильно b1 = b1 ^ b2; System.out.println(b1); >>

Презентацию с видео можно скачать на Patreon .

Источник

Java

© 2008 Наталия Македа
Все материалы блога защищены авторским правом. Любая перепечатка или использование материалов этого блога в коммерческих целях возможна лишь с письменного согласия автора. При некоммерческом использовании ссылка на блог обязательна.

среда, 20 августа 2008 г.

2.7 Укороченные (short-circuit) логические операторы (Выпуск 10)

Укороченные (short-circuit) логические операторы && и || предназначаются для логических AND (И) и OR (ИЛИ) операций над выражениями типа boolean . Заметьте, что для XOR (исключающее ИЛИ) операции не существует укороченного логического оператора.

Укороченные логические операторы похожи на операторы & и |, но в отличие от них применяются только к выражениям типа boolean и никогда не применяются к интегральным типам. Тем не менее, && и || обладают замечательным свойством: они укорачивают вычисление выражения, если результат может быть дедуцирован из части выражения (чуть позже я поясню это на примерах). Благодаря этому свойству, операторы && и || широко используются для обработки null-выражений. Они также помогают увеличить эффективность всей программы.

  • выражение с AND оператором ложно ( false ), если значение хотя бы одного из его операндов ложно;
  • выражение с OR оператором истинно ( true ), если значение хотя бы одного из его операндов истинно.
  • false AND X = false
  • true OR X = true

Рассмотрим пример кода, который выводит сообщение String , если строка не нулевая и более 20 символов длиной:

Эта же задача может быть закодиравана по-другому:

1. if (s != null) <
2. if (s.length() > 20) <
3. System.out.println(s);
4. >
5. >

Если бы строка s была null , то при вызове метода s.length() мы бы получили NullPointerException . Ни в одном из двух примеров кода, однако, такая ситауция не возникнет. В частности, во втором примере, s.length() не вызывается при s = null , благодаря использованию укороченного оператора &&. Если бы тест (s!=null) возвращал ложь ( false ), то есть s - несуществующая строка, то и всё выражение гарантированно ложно. Значит, отпадает необхеодимость вычислять значение второго операнда, то есть выражения (s.length()>20) .

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

// первый пример 1. int val = (int)(2 * Math.random()); 2. boolean test = (val == 0) || (++val == 2); 3. System.out.println(“test = “ + test + “\nval = “ + val); // второй пример 1. int val = (int)(2 * Math.random()); 2. boolean test = (val == 0)|(++val == 2); 3. System.out.println(“test = “ + test + “\nval = “ + val);

Второй пример иногда будет выводить на печать вот это:

А дело вот в чём. Если val равно 0, то второй операнд (++val) никогда не будет вычислен, то есть val останется равным нулю. Если же изначально val равен единице, то в результате эта переменная будет инкрементирована и мы увидим val = 2 . Во втором примере, при использовании неукороченных операторов, инкремент выполняется всегда и результат будет всегда или 1 или 2 в зависимости от случайного значения выбранного на первом шаге. В обоих примерах переменная test принимает значение true , потому что либо val = 0 , либо val = 1 и инкрементируется до значения 2.

  • Они применяются к операндам типа boolean ;
  • Они вычисляют значение правого операнда только если результат не может быть вычислен на основании значения левого операнда:
    • false AND X = false
    • true OR X = true

    Источник

Оцените статью