Why does (i<=j && j<=i && i!=j) evaluate to TRUE?
JavaJava Problem Overview
I have written a piece of Java code which is running in an infinite loop.
Below is the code:
public class TestProgram {
public static void main(String[] args){
Integer i = new Integer(0);
Integer j = new Integer(0);
while(i<=j && j<=i && i!=j){
System.out.println(i);
}
}
}
In the code above, while seeing the condition in the while
loop, at first it looks like that program will not go inside the while
loop. But actually it is an infinite loop and keeps printing the value.
What is happening here?
Java Solutions
Solution 1 - Java
-
i <= j
is evaluated totrue
, because auto unboxing happens for int comparisons and then bothi
andj
hold the default value,0
. -
j <= i
is evaluated totrue
because of the above reason. -
i != j
is evaluated totrue
, because bothi
andj
are different objects. And while comparing objects, there isn't any need of auto unboxing.
All the conditions are true, and you are not changing i
and j
in loop, so it is running infinitely.
Solution 2 - Java
Because you are comparing
-
0 < = 0 (true) // unboxing
-
0 > = 0 (true) // unboxing
-
reference != secondReference (true)
as you are creating objects, not a primitive comparison. So it evaluates towhile(true) { // Never ending loop }
.
Solution 3 - Java
The integer objects are different. It is different from the basic int type.
See this answer: https://stackoverflow.com/questions/1514910/when-comparing-two-integers-in-java-does-auto-unboxing-occur
The i != j
part is true, which you were expecting to be false.
Solution 4 - Java
There are two different cases which we have to understand first,
case 1:
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println((i<=j && j<=i && i!=j));
System.out.println(i!=j);
case 2:
Integer i = 10;
Integer j = 10;
System.out.println((i<=j && j<=i && i==j));
System.out.println(i==j);
both are different, as
in case 1: i!=j
will be true
because both referencing to two different object in heap and can't be same. But
in case 2: i==j
will be true
because both 10 are integer literals and Java maintains pool for Integer literals
which have value (-128 <= X <= 127)
. So, in this case 10<=127 results true, So both will have reference to same object.
Solution 5 - Java
The loop is not ending because your condition is true( i != j is true because there are 2 different objects, use Integer.valueOf instead) and inside the loop the values are not changing so your condition remains true forever.
Solution 6 - Java
Perhaps the reason is that both 'i' and 'j' are objects, and object comparison is not the same as object reference comparison. Please consider using !i.equals(j) instead of i!=j
Solution 7 - Java
The integer objects are different. It is different from the basic int type. so you can just do like that. what you do it's just compare the object and of course the result is true.
Solution 8 - Java
> Integer a = new Integer(0); > Integer b = new Integer(0);
The <= and >= comparisons will use the unboxed value 0, while the != will compare the references and will succeed since they are different objects.
Even this will also works i,e
> Integer a = 1000; Integer b = 1000;
but this doesnot :
> Integer a = 100; Integer b = 100;
The reason is because Integer internally uses caching for Integer objects between -128 and 127 and return instances from that cache for the range it covers. I am not sure but I guess you can also change its maximum value in package "java.lang.Integer.IntegerCache.high".
For better understanding check url : https://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching
Solution 9 - Java
The program keeps on displaying the same value of i
because you aren't incrementing or decrementing either the value of i
or j
. The condition in the for always keeps evaluating to true, so it is an infinite loop.
Solution 10 - Java
you have to know its a bit different in && this and this & when you use && then when first condition is true then it check second condition if its false then it not checked third condition because in & operator if one condition is false all of the statement is false if use || then if it see true then it return true in your code because i and j is equal first and second condition are true then in third condition it will be false because they are equal and while condition is false .