3

I have this code:

class ABC
{
    public static void main(String[] args) {
        Integer inta = new Integer(10);
        Integer intb = new Integer(10);
        if (inta <= intb) {
            System.out.println("inta is less than intb");
        }
        if (inta >= intb) {
            System.out.println("inta is greater than intb");
        }
        if (inta != intb) {
            System.out.println("inta is not equal to intb");
        }
    }
}

This outputs:

inta is less than intb
inta is greater than intb
inta is not equal to intb

Can anyone explain why this happens? How can an object be equal and not equal at the same time?

Cole Tobin
  • 9,206
  • 15
  • 49
  • 74
Jigar
  • 300
  • 4
  • 13
  • You could also try with `Integer inta = 10; Integer intb = 10;` and you will get different results. – assylias Dec 14 '13 at 17:13
  • 3
    @ColeJohnson This has nothing to do with the cache. – assylias Dec 14 '13 at 17:15
  • @assylias I tried with it and got following output inta is less than intb inta is greater than intb – Jigar Dec 14 '13 at 17:15
  • 1
    `<=` is "less than or equal to", and `>=` is "greater than or equal to". And == checks if they're the same object, which they're not. Use compareTo() and check the value returned from that instead. – splrs Dec 14 '13 at 17:18
  • 2
    @cole isn't that what op is doing and getting false? I think you misunderstood where the cache applies. – Sotirios Delimanolis Dec 14 '13 at 17:24
  • @Sotirios I probably do misunderstand it because I avoid the wrapper classes at all costs in my programming. – Cole Tobin Dec 14 '13 at 17:37
  • To elaborate on splrs' comment, your code is working as you've told it to. Instead of `>=` and `<=`, you should be using `>` and `<`, and `.equals()` or `.compareTo()` instead of `==`. The first two conditions you have are always satisfied because 10 always **equals** 10. The last condition is always `false` because `inta` and `intb` are two distinct object **references**. – spork Dec 14 '13 at 17:42

3 Answers3

2

It satisfies the first and second ones because the compiler needs primitive types for greater-than (>) or less-than comparison (<) operations, so it makes an auto unboxing from Integer to int. Because you use the or-equal-to operators (<= and >=), the conditional is true.

It satisfies the third one because the compiler checks two Integer object to see if they are the same object, and since they are not, the conditional is true.

Cole Tobin
  • 9,206
  • 15
  • 49
  • 74
Salih Erikci
  • 5,076
  • 12
  • 39
  • 69
1

Wrapper objects are still objects; if one performs object equivalence on them (==), then unless they're the exact same reference, that will always be false.

Unboxing happens because we're using relational operators, which will unbox to a type that can be respected by the operators - in this case, int. The comparison happens as if you didn't have the wrappers.

Things get interesting if you use the fact that Integer can be cached through the use of valueOf().

If your expression appeared as such:

Integer inta = Integer.valueOf(10);
Integer intb = Integer.valueOf(10);

...then performing inta == intb would equal true, since both values are between the cached range of [-128, 127].

Since you're attempting to see if a value is larger than, greater than, or equal to another, then consider using Comparable instead. An Integer is a Comparable entity, so you can simply do this:

System.out.println(inta.compareTo(intb) < 0); // to check for a < b
System.out.println(inta.compareTo(intb) == 0); // to check for a == b
System.out.println(inta.compareTo(intb) > 0); // to check for a > b
Community
  • 1
  • 1
Makoto
  • 104,088
  • 27
  • 192
  • 230
0

Use inta.compareTo(intb) and check the value returned.

http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#compareTo%28java.lang.Integer%29

e.g.

int res = inta.compareTo(intb);
if (res < 0)
{
    System.out.println("inta is less than intb");
}
if (res > 0)
{
    System.out.println("inta is greater than intb");
}
if (res != 0)
{
    System.out.println("inta is not equal to intb");
}

To repeat my comment on the OP: The operators used in the first two tests are incorrect, as they test "less and or equal to" and "greater than or equal to", and changing those to < and > would work for those as the underlying int is unboxed in those cases. However, == is checking whether they're the same object, which they're not, so it will return false unless you have something like inta == inta.

splrs
  • 2,424
  • 2
  • 19
  • 29