Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does == comparison use byte in ArrayList comparisons? [duplicate]

In a program I was working on, I ran into a data storage issue, specifically related to ArrayLists. This is not the actual code I was testing, but it provides an example of what I mean.

public class test
{
  public static void test()
  {
    ArrayList<Integer> bob = new ArrayList<Integer>();
    bob.add(129);
    bob.add(129);
    System.out.println(bob.get(0) == 129 );
    System.out.println(bob.get(1) == 129 );
    System.out.println(bob.get(0)  == bob.get(1) );
  }
}

If you run it, you get, true, true, and false. The code recognizes that both are equal to 129 but for some reason returns false when it attempts to see if they are equal to each other. However, if you change the value to 127, it returns true, true, and true. Testing this multiple times for different values and you will see that the minimum value to receive true, true, and true is -128 and the maximum is 127. This is the interval for byte, which leads me to suspect that the == operation uses byte in this case.

What is interesting is that if you modify the code so that it reads

public class test
{
  public static void test()
  {
    ArrayList<Integer> bob = new ArrayList<Integer>();
    bob.add(129);
    bob.add(129);
    int a = bob.get(0);
    int b = bob.get(1);

    System.out.println(a == 129 );
    System.out.println(b == 129 );
    System.out.println(a == b );
  }
}

it works just as intended. true, true, and true are outputted. Why does saving the values as int before the comparison change the outcome? Is it because if they are not saved, the comparison will use byte by default for the == comparison?

like image 958
Sanum Avatar asked May 29 '14 04:05

Sanum


1 Answers

The answer lies in the caching mechanism of the primitive wrapper classes that Java employs.
In the case of an Integer, there's caching for the values between -128 to 127 (i.e. the value range of a byte).

This means that if you box any value between -128 to 127, you get a ready made instance from the cache. This is why the == operator works for those, as it compares the references rather than the values.
On the other hand, if you're using any other value, you'll get a fresh new instance per boxing, which means that the == operator will fail.

Here's the piece of code from the Integer class that's responsible for this:

private static class IntegerCache {
    private IntegerCache(){}

    static final Integer cache[] = new Integer[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Integer(i - 128);
    }
}
like image 66
ethanfar Avatar answered Sep 19 '22 05:09

ethanfar