Reputation: 43
A multipurpose field in an Object of type ObjectHolder contains an Object obj. obj might store a wrapped primitive or an array of primitives. How can we compare two objs if they are arrays? A simplified example:
import java.util.Arrays;
public class ObjectHolder {
public Object obj;
public static void main(String[] args) {
ObjectHolder oh1 = new ObjectHolder();
oh1.obj = new int[]{ 3, 4, 5 };
ObjectHolder oh2 = new ObjectHolder();
oh2.obj = new int[]{ 3, 4, 5 };
if (oh1.obj.getClass().isArray() && oh2.obj.getClass().isArray()) {
System.out.println("We know both objects are arrays.");
// System.out.println(Arrays.equals(oh1.obj, oh2.obj));
}
}
}
The commented-out line causes the compile to break.
Note- the array can be of any primitive type (or String), so simply casting it to int[] is not a convenient general solution.
Upvotes: 4
Views: 98
Reputation: 63
In this case Java Reflections will do the job (idea from question Java Array Comparison):
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class ObjectHolder {
public Object obj;
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
ObjectHolder oh1 = new ObjectHolder();
oh1.obj = new int[] { 3, 4, 5 };
ObjectHolder oh2 = new ObjectHolder();
oh2.obj = new int[] { 3, 4, 6 };
if (oh1.obj.getClass().isArray() && oh1.obj.getClass().equals(oh2.obj.getClass())) {
Class<?> c = oh1.obj.getClass();
if (!c.getComponentType().isPrimitive()) {
c = Object[].class;
}
Method m = Arrays.class.getMethod("deepEquals", c, c);
System.out.println((Boolean) m.invoke(null, oh1.obj, oh2.obj));
}
}
}
I think the way @Andreas pointed out in his edited answer the following way might be a shorter, better and cleaner solution than using Java Reflections:
if(oh1.obj.getClass().isArray() && oh1.obj.getClass().equals(oh2.obj.getClass())) {
System.out.println(Arrays.deepEquals(new Object[] { oh1.obj }, new Object[] { oh2.obj }))
}
Upvotes: 2
Reputation: 159086
Next, you verify that the arrays have the same component type by calling getComponentType()
, then call the appropriate overload of Arrays.equals()
(there are 9 of them).
UPDATED
Of course, it would be much easier to just call Arrays.deepEquals(Object[] a1, Object[] a2)
, since it already has all the logic of doing that.
if (Arrays.deepEquals(new Object[] { oh1.obj }, new Object[] { oh2.obj })) {
// They are equal, though they may not be arrays
}
To quote the javadoc, where e1 = oh1.obj
and e2 = oh2.obj
:
e1
ande2
are both arrays of object reference types, andArrays.deepEquals(e1, e2)
would return truee1
ande2
are arrays of the same primitive type, and the appropriate overloading ofArrays.equals(e1, e2)
would return true.e1 == e2
e1.equals(e2)
would return true.
Upvotes: 2