Java issue: equals() on Array of primitives

Have you tried to use .equals to compare Arrays of identical primitives only to find it always returns false? I was surprised using such an Array for the key of a Map. I expected equals to return true, but Java's dynamically generated class returns false unless the comparison is to the same actual object. I am considering filing a jdk issue, but first wanted to check and see what others expected equals to do in this case. Again, this is a Java issue, not an IDEA.

Thanks,
Jon

10 comments

Jon Steelman wrote:

Have you tried to use .equals to compare Arrays of identical primitives only to find it always returns false? I was surprised using such an Array for the key of a Map. I expected equals to return true, but Java's dynamically generated class returns false unless the comparison is to the same actual object. I am considering filing a jdk issue, but first wanted to check and see what others expected equals to do in this case. Again, this is a Java issue, not an IDEA.

Thanks,
Jon



This should give the result you want.

Arrays.equals(primitiveArrayA, primitiveArrayB)

Not sure if there is a way to make this be the equals() for Map keys.

0

Err, the Object.equals implementation compares references. int[] extends Object and does not override equals.

Object l = new int[]{1, 2};
Object r = new int[]{1, 2};
boolean b = l == r; // b == false, and thus:
b = l.equals(r); // b == false

0

Yeah, that's what I need it for, the map key. I could always create my own holder class and use the method you've pointed out, but I was more wondering if Java should do what I'm describing by default.

Thanks,
Jon

0

There is not a question about the obvious behavior of the current equals implementation. To ask again the question from the post: shouldn't Java's array wrapping of primitives equals() implementation be smart enough to allow arrays of the same primitive type to be compared properly using equals?

0


1) You'll never get get such a change through the JCP. It would break too much existing code.

2) The static equals() methods in java.util.Arrays have the deep equality semantics you want.

3) Funny you should mention this. I'm just polishing up an inspection for calling .equals() on arrays. The problem is what to have the quick-fix do. I could have it change the check to ==, which has equivalent semantics but is more obvious, or I could have it change to Arrays.equals(), which is more likly to be what the programmer intended. Still working on it.

--Dave Griffith

0

You would probably also want hashCode() and toString() on arrays. But using arrays as keys in a Map this way would probably be very slow as all array elements would have to be compared almost every time.

Alos this can't be changed in the jdk anymore. The change would be incompatible. Unfortunate as Arrays.equals() can't be called on arrays with multiple dimensions.
See sun bugs:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4171916
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4168079

0

1) Okay, I guess you could say it would break existing code that relies on .equals being identical to ==

3) How about another inspection that warns if somebody tries to use an array as a key to a Map?

Thanks,
Jon

0


Arrays as map keys is a reasonable inspection, if a bit of an edge case. Should it also do arrays as set contents (which also have the implicit .equals())?

--Dave Griffith

0

Thanks, that would be great. I think the set case is reasonable too. Otherwise, you could add content identical arrays over and over and have the set contain all of them individually.

Jon

0

Bas Leijdekkers wrote:

You would probably also want hashCode() and toString() on arrays. But using arrays as keys in a Map this way would probably be very slow as all array elements would have to be compared almost every time.


If the arrays could be guaranteed to be immutable you could wrap the
array in a class which holds in a final field and implements hashCode
and toString methods which lazily evaluate and cache their results, and
an equals method which uses Arrays.equals.

Ciao,
Gordon

--
Gordon Tyler (Software Developer)
Quest Software <http://www.quest.com/>
260 King Street East, Toronto, Ontario M5A 4L5, Canada
Voice: (416) 933-5046 | Fax: (416) 933-5001

0

Please sign in to leave a comment.