0

I want to compare the values of two arrays of type Integer. I get the wrong answer when I compare their exact values, and the correct answer when I compare them with Arrays.equals:

    Integer a[]=new Integer[2];
    Integer b[]=new Integer[2];
    a[0]=138;
    a[1]=0;
    b[0]=138;
    b[1]=0;
    boolean c;
    c=a[0]==b[0];//c is false
    c=Integer.valueOf(a[0])==Integer.valueOf(b[0]);//c is false
    c=Arrays.equals(a, b);//c is true
Pegah
  • 672
  • 2
  • 13
  • 23

3 Answers3

5

You're looking for intValue, not Integer.valueOf (though it's easy to see how you could get them confused!):

c = a[0].intValue() == b[0].intValue();

Java has primitive types (int, byte, double, etc.) and also reference types (objects) corresponding to them for those situations where you need an object. Your code doing a[0] = 138; is auto-boxing the primitive value 138 inside an Integer instance.

intValue returns the primitive int contained by an Integer instance. Integer.valueOf is used for getting an Integer instance (from an int or a String — in your case, it'll use valueOf(int) by auto-un-boxing your Integer reference).

You can also do this:

c = (int)a[0] == (int)b[0];

...which will trigger auto-unboxing.

More about boxing (including auto-boxing and unboxing) in the specification.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks for your complete answer.a and b were values of a Hash, and it was the reason that they were Integer. – Pegah Apr 23 '12 at 18:08
2

You are doing implicit type conversion (auto-boxing) in your code.

The line:

a[0]=138;

actually translates to:

a[0] = Integer.valueOf(138);

creating an instance of Integer. The catch is that this method caches Integers from -128 to 127(How large is the Integer cache?) and creates new instance for values higher then 127 , hence == comparison returns false.

/**
 * Returns an {@code Integer} instance representing the specified
 * {@code int} value.  If a new {@code Integer} instance is not
 * required, this method should generally be used in preference to
 * the constructor {@link #Integer(int)}, as this method is likely
 * to yield significantly better space and time performance by
 * caching frequently requested values.
 *
 * This method will always cache values in the range -128 to 127,
 * inclusive, and may cache other values outside of this range.
 *
 * @param  i an {@code int} value.
 * @return an {@code Integer} instance representing {@code i}.
 * @since  1.5
 */
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

Note that actual type of a[0] is an Integer, so you can write

c=a[0].equals(b[0]);

which will return true.

Languoguang
  • 2,166
  • 2
  • 10
  • 15
Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
0

Because of the arrays, I don't think the inner values are going to get automatically unboxed for you. this might work if you had an int[] instead of an Integer[]

JRaymond
  • 11,625
  • 5
  • 37
  • 40