【问题标题】:Comparing arrays that have been stored as Objects比较已存储为对象的数组
【发布时间】:2017-02-23 02:44:01
【问题描述】:

ObjectHolder 类型的 Object 中的多用途字段包含 Object objobj 可能存储一个包装的基元或基元数组。如果它们是数组,我们如何比较两个 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版本的?好像没找到
  • @Tibrogargan - 我不这么认为,他说的是 ObjectHolder
  • @ItamarGreen 是的,他是:“如果它们是数组,我们如何比较两个 obj?”。他已经拥有的 ObjectHolder 部件
  • @Tibrogargan 您错过了数组可能不是 int[] 对象的观点。它们可以是float[]boolean[]String[]Object[]Long[],或者您可以想象的任何其他内容。阅读问题的最后一句话:注意-数组可以是任何原始类型(或字符串),因此简单地将其转换为 int[] 并不是一个方便的通用解决方案。我>

标签: java arrays object


【解决方案1】:

在这种情况下,Java 反射将完成这项工作(来自问题 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));
        }
    }
}

更新

我认为@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 }))
}

【讨论】:

    【解决方案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。

    【讨论】:

    • 如果对象不是数组,这似乎也适用于[对于某些对象]。
    猜你喜欢
    • 2020-01-15
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多