&& 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.
3 answers
- The operators
|
and||
are logical operatorsИЛИ
. It works like this: if at least one condition istrue
, then all the result is true. I.e., if one condition isfalse
and the other istrue
, then the result is true. - The operators
&
and&&
are logical operatorsИ
. It works like this: if at least one condition isfalse
, then the result isfalse
. In other words, for the result to betrue
, both conditions must betrue
.
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
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).
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