如何使用自定义键类型使HashMap正常工作?

Mil*_*hev 8 java types key hashmap

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

HashMap<Pair<Integer, Integer>, StrategyPoint> myMap = new HashMap<Pair<Integer, Integer>, StrategyPoint> ();
Run Code Online (Sandbox Code Playgroud)

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

我明显错过了一些东西,更有可能我应该以某种方式定义一种比较我的Pair班级实例的方法.但是我尝试compareTo在我的Pair课堂上实现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));
Run Code Online (Sandbox Code Playgroud)

执行的结果是:

false

true
Run Code Online (Sandbox Code Playgroud)

我调试了它,搜索器实例正在正确填充,但似乎HashMap拒绝在其中找到它keySet.

Pet*_*hev 14

你必须正确地实现equalshashCodePair类.

HashMap使用这些方法来区分和哈希键类.


Nis*_*hth 5

你需要equals在课堂上覆盖Pair.此方法的实现定义了两个对象Pair被认为是相等的.

每当你覆盖时,equals你必须总是覆盖hashcode.

当你覆盖equals而不是hashcode(来自Effective Java,Second Ed.)时,可能会出现问题:

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

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

有一套必须符合的实施规则equals.另一套覆盖规则hashcode.

  • 迟到并没有那么有用. (4认同)
  • 在投反对票时,您完全忘记了 hashCode,这使您的答案完全错误(因此没有用)。不要试图改写历史。我删除了我的反对票,因为现在答案已经确定。 (2认同)