如何使用自定义键类型使HashMap正常工作?
我认为我的问题很简单,但我找不到解决方案所以我决定在这里问一下。 我需要的是使用这样的自定义Key类型创建一个HashMap
:
HashMap<Pair, StrategyPoint> myMap = new HashMap<Pair, StrategyPoint> ();
但是我在这里遗漏了一些东西,因为HashMap
停止正常工作。 首先,Key变得不唯一,并且可以在keySet
找到具有相同值的Pair的不同实例。 包含键function也不像我想的那样工作:)。
我明显错过了一些东西,更有可能我应该以某种方式定义一种方法来比较我的Pair
类中的实例。 但是我尝试在我的Pair
类中使用compareTo
实现Comparable,但它仍然无效。 有什么建议么?
我的原始代码有点混乱,读起来不友好,所以我举一个例子来说明我的问题。
这是代码:
HashMap<Pair, StrategyPoint> myMap = new HashMap<Pair, StrategyPoint> (); Pair myPair = new Pair(2,2); StrategyPoint myPoint= new StrategyPoint(2, 2, 5, 5, false); myMap.put(myPair, myPoint); Pair searcher = new Pair (0,0); searcher.setFirst(2); searcher.setSecond(2); System.out.println(myMap.containsKey(searcher)); System.out.println(myMap.containsKey(myPair));
执行的结果是:
false true
我已经调试它并正确填充了搜索器实例,但似乎HashMap
拒绝在其keySet
找到它。
您必须在Pair
类上正确实现equals
和hashCode
。
HashMap
使用这些方法来区分和散列密钥类。
您需要在类Pair
覆盖equals
。 此方法的实现定义了Pair
两个对象如何被视为相等。
每当你重写equals
你必须始终覆盖hashcode
。
当你重写equals
而不是hashcode
时,可能会出现问题(来自Effective Java,Second Ed。):
根据类的equals方法,两个不同的实例在逻辑上可能相等,但是对于Object的hashCode方法,它们只是两个没有多少共同点的对象。 因此,Object的hashCode方法返回两个看似随机的数字,而不是合同要求的两个相等的数字。
因为两个逻辑上相等的实例的哈希码变得不相等,如果您尝试搜索一个而另一个在集合中,则最终会查找错误的哈希桶,从而导致null
。
有一套规则 , equals
实现必须符合。 用于覆盖hashcode
另一组规则 。
你的Pair类需要根据Javadoc for Object
指定的契约实现hashCode()
和equals()
。