将存储为对象的数组进行比较

4

ObjectHolder类型对象中的一个多功能字段包含一个obj对象,obj可以存储一个封装的基本类型或者一个基本类型数组。如果它们是数组,我们该如何比较两个obj?以下是一个简单的示例:

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));
        }   
    }   

}   

被注释的代码会导致编译出错。

注意- 数组可以是任何基本类型(或字符串),因此仅将其强制转换为int []不是一个方便的通用解决方案。


这是哪个Java版本?我似乎找不到它。 - ItamarG3
1
@Tibrogargan - 我不这么认为,在这里他谈论的是ObjectHolder。 - ItamarG3
@ItamarGreen 是的,他是这样问的:“如果它们是数组,我们如何比较两个对象?”他已经有了 ObjectHolder 部分。 - Tibrogargan
1
@Tibrogargan,你没有理解到数组可能不是int[]对象的要点。它们可以是float[]boolean[]String[]Object[]Long[]或者其他你能想到的类型。请读一下问题的最后一句话:注意- 数组可以是任何基本类型(或字符串),所以简单地将其强制转换为int[]并不是一个方便的通用解决方案。 - Andreas
显示剩余3条评论
2个回答

2
接下来,您可以通过调用getComponentType()验证数组具有相同的组件类型,然后调用适当重载的Arrays.equals()(共9个)进行比较。 更新 当然,更简单的方法是直接调用Arrays.deepEquals(Object[] a1, Object[] a2),因为它已经具备了所有相关逻辑。
if (Arrays.deepEquals(new Object[] { oh1.obj }, new Object[] { oh2.obj })) {
    // They are equal, though they may not be arrays
}

引用javadoc,其中e1 = oh1.obje2 = oh2.obj

  • e1e2都是对象引用类型的数组,并且Arrays.deepEquals(e1, e2)将返回true
  • e1e2是相同原始类型的数组,并且Arrays.equals(e1, e2)适当重载将返回true。
  • e1 == e2
  • e1.equals(e2)将返回true。

1
如果这些对象不是数组,似乎这也可以适用于它们。 - Tibrogargan

2
在这种情况下,Java反射将完成工作(来自问题Java数组比较的想法):
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));
        }
    }
}

更新

我认为@Andreas在他编辑的答案中指出的以下方法可能比使用Java反射更短、更好、更清晰:

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 }))
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接