&& and || and their brothers & and | in different situations. What are their differences?

Friends! I would like to ask about && and ||. If a double ampersand is used and the first expression is false, the second expression will not even be checked, because regardless of it,the entire expression will be false. With a single ampersand, both conditions will be calculated.

Everything is clear, but does it make sense to have a double ampersand in the YAP? I looked, used it, honestly did not understand why they were invented by 2. All my results as soon as I didn't do it came out the same.

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

Yeah I know that && it checks the first value and if it is false, then not even the checks, then the question is: do we Need in this case(single ampersand)? Please describe examples where there are differences & from the && and where they may work, because I saw only the same work.

Author: Anton Sorokin, 2018-10-18

3 answers

  • The operators | and || are logical operators ИЛИ. It works like this: if at least one condition is true, then all the result is true. I.e., if one condition is false and the other is true, then the result is true.
  • The operators & and && are logical operators И. It works like this: if at least one condition is false, then the result is false. In other words, for the result to be true, both conditions must be true.

Let's say you have such a check: checkFirst() && checkSecond().

boolean method checkSecond():

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

And this label may or may not be output to the console. And if you specified &, it would always be output, even if checkFirst returned false. That is, sometimes you need to check both conditions, regardless of whether it affects anything. And && was invented to improve performance, you never know what cumbersome checks you have-so that they are not performed once again.

P.S. Andrey NOP wrote in in the comments to the question about side effects, println above - this is just a side effect. Instead of println, you can assign some value to an important field, etc.

UPD:

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) {
    System.out.println("Вызван checkSecond");
    if (i == 0)
        return true;

    return false;
}

Conclusion:

Вызван checkFirst
Вызван checkSecond
Первое условие выполнено

Вызван checkFirst

Вызван checkFirst
Вызван checkSecond
Третье условие выполнено

Вызван checkFirst
Вызван checkSecond
 13
Author: Anton Sorokin, 2019-03-24 05:24:38

The simplest example. Let's say there is an array of size 10:

if(i < 10 && a[i] == 0) { ... }

if(i < 10 & a[i] == 0) { ... }

For i >= 10, in the second case (&), when checking the condition, an attempt will be made to access the element outside the array boundaries, in the first case (&&) everything will work correctly (the right part of the condition will not be checked, because the left part of the condition is false).

 10
Author: insolor, 2018-10-18 12:01:04

In some cases, you need to calculate both operands of a logical operator in order to show side effects:

class SideEffects {
    public static void main(String args[]) {
    int i = 0;
    /*Значение переменной i инкрементируется, несмотря на то что проверяемое условие в операторе if ложно */
    if(false & (++i < 100)) System.out.println("Эта строка не будет отображаться");
    System.out.println("Оператор if выполняется: " + i); // отображается 1
    
    /* В данном случае значение переменной i не инкрементируется, т.к. второй операнд укороченного логического оператора не вычисляется,а значит, инкремент пропускается */
    if(false && (++i < 100)) System.out.println("Эта строка не будет отображаться");
    System.out.println("Оператор if выполняется: " + i); //по-прежнему отображается 1 !!
    }
}

If the logic of the program requires that the second operand of a logical operator must necessarily be evaluated, you should use the usual, not shortened, forms of logical operations.

Source: Herbert Schildt. Java 8.Beginner's Guide, p. 78

 6
Author: dubnic, 2020-09-10 07:06:50