Java:比较HashMap <String,Object>如果value可能是Object []

Dmi*_*ank 7 java arrays equals

我有以下带有属性键和值的HashMap:

private HashMap<String, Object> prop_values;
Run Code Online (Sandbox Code Playgroud)

我需要检查它的一个实例是否等于另一个实例.在过去,我只是这样做:

if (prop_values_1.equals(prop_values_2)){
   //  do something
}
Run Code Online (Sandbox Code Playgroud)

这一直有效,直到我得到Object[]一个价值.所以,我以前表达总是返回false这样HashMap任何Object[]价值.

所以,我必须实现这个方法:

private boolean isPropValuesEquals(HashMap<String, Object> pv1, HashMap<String, Object> pv2){
   boolean isEquals = true;

   if (pv1 == null || pv2 == null){
      return false;
   }

   if (!pv1.keySet().equals(pv2.keySet())){
      return false;
   }

   for (String key : pv1.keySet()){

      Object cur_pv1 = pv1.get(key);
      Object cur_pv2 = pv2.get(key);

      if (cur_pv1 instanceof Object[]){
         if (cur_pv2 instanceof Object[]){
            isEquals = Arrays.equals((Object[])cur_pv1, (Object[])cur_pv2);
         } else {
            return false;
         }
      } else {
         isEquals = isEquals && cur_pv1.equals(cur_pv2);
      }

      if (!isEquals){
         return false;
      }
   }

   return isEquals;

}
Run Code Online (Sandbox Code Playgroud)

它有效,但它似乎是某种黑客,我不确定这是实现我需要的最佳方式.

那么,这里有两个问题:

  • 为什么Object [] .equals()与Arrays.equals()不一样?这似乎很痛苦.

  • 是否有更好的比较方法HashMap<String, Object>,如果值可以是Object[]

Joo*_*kka 3

深层的问题是没有办法覆盖equals()数组的。为什么它不首先写成“相同顺序的相等元素”,我不知道。它绝对可能是(除非有一些不这样做的模糊理由;我想不出任何理由;如果你想检查引用相等性,你可以使用==,那么工作 equals()危害会是什么?)。

您的解决方案就是要走的路。只需考虑几个细节:

  • x instanceof Object[]您可以使用代替x.getClass().isArray(),因此它也适用于其他数组,例如int[](不是子类Object[])。缺点:您可能需要单独检查是否xnull

  • 如果数组可能包含嵌套数组,请考虑使用Arrays.deepEquals().

原始数组不是s的演示Object[]

    Object a = new int[1];
    System.out.println("" + (a instanceof Object[])); // false
    System.out.println("" + a.getClass().isArray()); // true
Run Code Online (Sandbox Code Playgroud)

另一个令人头疼的问题是,即使您发现这x是一个数组,您仍然必须单独处理所有不同原始元素类型的情况。在 Java 的类型系统中无法以通用方式处理它们。当然,如果我们的映射中没有原始数组,那么您不需要处理这种情况。