9

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

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

但是我在这里遗漏了一些东西,因为HashMap停止正常工作。首先,Key 变得不唯一,并且可以在keySet. 此外,包含键功能也不能像我想象的那样工作:)。

我显然错过了一些东西,更有可能我应该以某种方式定义一种方法来比较我Pair班级中的实例。但是,我尝试compareToPair课堂上实现 Comparable with ,但它仍然不起作用。有什么建议么?

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

这是代码:

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.

4

3 回答 3

15

您必须在课堂equals上正确实施。hashCodePair

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

于 2013-02-23T09:56:36.967 回答
7

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

并且每当您覆盖时,equals您必须始终覆盖hashcode.

以下是您覆盖equals但未覆盖时可能出现的问题hashcode(来自 Effective Java,第二版。):

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

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

有一套实现必须遵守的规则。equals另一组覆盖规则hashcode

于 2013-02-23T10:00:10.143 回答
3

您的 Pair 类需要根据 Javadoc 中hashCode()为.equals()Object

于 2013-02-23T09:56:50.867 回答