【问题标题】:How to make HashMap work properly with custom key type?如何使 HashMap 与自定义键类型一起正常工作?
【发布时间】:2013-02-08 23:00:40
【问题描述】:

我认为我的问题很简单,但是我找不到解决方案,所以我决定在这里提问。我需要的是使用这样的自定义密钥类型制作HashMap

HashMap<Pair<Integer, Integer>, StrategyPoint> myMap = new HashMap<Pair<Integer, Integer>, StrategyPoint> ();

但是我在这里遗漏了一些东西,因为HashMap 停止正常工作。首先,密钥变得不唯一,并且可以在keySet 中找到具有相同值的 Pair 的不同实例。包含键功能也不能像我想象的那样工作:)。

我显然错过了一些东西,更有可能我应该以某种方式定义一种方法来比较我的 Pair 类中的实例。但是,我尝试在 Pair 类中使用 compareTo 实现 Comparable ,但它仍然无法正常工作。有什么建议吗?

我的原始代码有点乱,不友好,所以我在这里做了一个例子来说明我的问题。

代码如下:

HashMap<Pair<Integer, Integer>, StrategyPoint> myMap = new HashMap<Pair<Integer, Integer>, StrategyPoint> ();
    Pair<Integer, Integer> myPair = new Pair<Integer, Integer>(2,2);
    StrategyPoint myPoint= new StrategyPoint(2, 2, 5, 5, false);
    myMap.put(myPair, myPoint);


    Pair<Integer, Integer> searcher = new Pair<Integer, Integer> (0,0);
    searcher.setFirst(2);
    searcher.setSecond(2);
    System.out.println(myMap.containsKey(searcher));
    System.out.println(myMap.containsKey(myPair));

执行的结果是:

false

true

我已经对其进行了调试,并且搜索器实例已正确填充,但似乎HashMap 拒绝在其keySet 中找到它。

【问题讨论】:

    标签: java types hashmap key


    【解决方案1】:

    您必须在Pair 类上正确实现equalshashCode

    HashMap 使用这些方法来区分和散列密钥类。

    【讨论】:

      【解决方案2】:

      您需要覆盖Pair 类中的equals。该方法的实现定义了Pair 的两个对象如何被视为相等。

      并且无论何时覆盖equals,都必须始终覆盖hashcode

      当您覆盖 equals 而不是 hashcode(来自 Effective Java,第二版)时,可能会出现以下问题:

      根据一个类的不同,两个不同的实例在逻辑上可能相等 equals 方法,但是对于 Object 的 hashCode 方法,它们只是两个 没有太多共同点的对象。因此 Object 的 hashCode 方法返回两个看似随机的数字,而不是两个相等 合同要求的数量。

      由于两个逻辑上相等的实例的哈希码变得不相等,如果您尝试在集合中搜索一个时,您最终会查找错误的哈希桶,从而导致null

      rules 的实现必须符合一组 rules。另一组rules 用于覆盖hashcode

      【讨论】:

      • -1:您的回答迟了,而且不完整。另外两个已经是正确的了。
      • 在投反对票时,您完全忘记了 hashCode,这使您的答案明显错误(因此没有用)。不要试图改写历史。我删除了我的反对票,因为答案现在已经确定。
      • 是啊是啊,先生——我听到了命令,我明白了,我会遵守命令的:)
      【解决方案3】:

      您的 Pair 类需要根据 Javadoc 中为 Object 指定的协定实现 hashCode()equals()

      【讨论】:

        猜你喜欢
        • 2012-03-16
        • 2023-04-07
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-10
        • 1970-01-01
        • 2016-08-30
        相关资源
        最近更新 更多