Java: compare HashMap<String, Object> if value might be an Object[]
The deep problem is that an there's no way to override the equals()
of an array. Why it's not written as "equal elements in the same order" in the first place, I have no idea. It definitely could have been (unless there's some obscure rationale for not doing it; I can't think of any; if you wanted to check for reference equality, you use ==
, so what would a working equals()
harm?).
Your solution is the way to go. Just a couple of details to consider:
Instead of
x instanceof Object[]
, you could usex.getClass().isArray()
, so it would work for other arrays as well, such asint[]
(which is not a subclass ofObject[]
). Downside: you may have to separately check ifx
isnull
.If the arrays may contain nested arrays, consider using
Arrays.deepEquals()
.
A demonstration that primitive arrays are not Object[]
s:
Object a = new int[1]; System.out.println("" + (a instanceof Object[])); // false System.out.println("" + a.getClass().isArray()); // true
Yet another pain in the arse is that even if you find that x
is an array, you still have to handle separately cases for all the different primitive element types. There's no way to handle them in a generic way in Java's type system. Of course, if you don't have primitive arrays in our map, then you don't need to handle this case.
Equality can be different things: is it the same reference (reference equality)? Or does it have the same contents?
The issue with arrays is that they are mutable. equals
and hashCode
of an object must always come as pairs, and the hash code should not change (otherwise objects cannot be found in hash tables). Therefore the normal equals
(and hashCode
) cannot use the arrays content, they have to rely on another (non-mutable) property of the array, which is the reference.