Java HashMap with Int Array

2022-09-01 21:52:07

我正在使用此代码来检查数组是否存在于:HashMap

public class Test {
    public static void main(String[] arg) {
        HashMap<int[], String> map = new HashMap<int[], String>();
        map.put(new int[]{1, 2}, "sun");
        System.out.println(map.containsKey((new int[]{1, 2})));
    }
}

但是这打印.如何检查数组是否存在于 ?FalseHashMap


答案 1

问题是因为两者并不相等。int[]

System.out.println(
    (new int[] { 1, 2 }).equals(new int[] { 1, 2 })
); // prints "false"

Map和其他 Java Collections Framework 类根据 .从地图 API:equals

集合框架接口中的许多方法都是根据方法定义的。例如,该方法的规范说:“当且仅当此映射包含键的映射时返回,这样。equalscontainsKey(Object key)truek(key==null ? k==null : key.equals(k))

请注意,它们不必是同一个对象;他们只需要.Java 中的数组从 扩展,其默认实现仅在对象标识上返回 true;因此,为什么它打印在上面的片段中。equalsObjectequalsfalse


您可以通过以下多种方式之一解决问题:

  • 为使用 java.util.Arrays 方法的数组定义自己的包装类。equalsequals/deepEquals
    • 而且别忘了,当你,你也必须@Override equals(Object)@Override hashCode
  • 使用类似的东西定义它们所包含的值List<Integer>equals
  • 或者,如果你能使用参考相等,你可以坚持你所拥有的。就像你不应该期望上面的片段被打印出来一样,你永远不应该期望能够仅仅通过它的值找到你的数组;您必须每次都坚持并使用原始引用。equalstrue

另请参阅:

应用程序接口

  • Object.equalsObject.hashCode
    • 对于Java程序员来说,了解这些契约以及如何使它们与系统的其余部分一起工作是至关重要的。

答案 2

您正在比较两个不同的引用。像这样的东西会起作用:

public class Test {
    public static void main(String[] arg)
    {
     HashMap<int[],String> map= new HashMap<int[],String>();
     int[] a = new int[]{1,2};
     map.put(a, "sun");
     System.out.println(map.containsKey(a));
    }
}

由于 是相同的引用,因此您将按预期接收。如果您的应用程序没有传递引用来执行比较的选项,我将创建一个新的对象类型,其中包含并重写该方法(不要忘记同时重写),以便这将反映在调用中。atrueint[]equals()hashCode()containsKey()