Why does (i<=j && j<=i && i!=j) evaluate to TRUE?

Java

Java 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 to true, because auto unboxing happens for int comparisons and then both i and j hold the default value, 0.

  • j <= i is evaluated to true because of the above reason.

  • i != j is evaluated to true, because both i and j 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 to while(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 .

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKshitij JainView Question on Stackoverflow
Solution 1 - JavaJuned AhsanView Answer on Stackoverflow
Solution 2 - JavaAshwaniView Answer on Stackoverflow
Solution 3 - JavaColonel PanicView Answer on Stackoverflow
Solution 4 - JavaAkhilesh Dhar DubeyView Answer on Stackoverflow
Solution 5 - JavaSilviu BurceaView Answer on Stackoverflow
Solution 6 - JavaEric GopakView Answer on Stackoverflow
Solution 7 - JavaKrichevskoyView Answer on Stackoverflow
Solution 8 - JavaWaheedView Answer on Stackoverflow
Solution 9 - Javauser28646View Answer on Stackoverflow
Solution 10 - Javasara SodagariView Answer on Stackoverflow