2011-05-14 103 views
6

我遇到了一个有趣的问题,我敢肯定是HashMap的错。请看下面的调试代码(AMAP是一个HashMap,关键是传递给此方法的值)HashMap说钥匙不存在,即使它

System.out.println("getBValues - Given: " + key); 
System.out.println("getBValues - Contains Key: " + AMap.containsKey(key)); 
System.out.println("getBValues - Value: " + AMap.get(key)); 
for(Map.Entry<A,HashSet<B>> entry : AMap.entrySet()) { 
    System.out.println("getBValues(key) - Equal: " + (key.equals(entry.getKey()))); 
    System.out.println("getBValues(key) - HashCode Equal: "+(key.hashCode() == entry.getKey().hashCode())); 
    System.out.println("getBValues(key) - Key: " + entry.getKey()); 
    System.out.println("getBValues(key) - Value: " + entry.getValue()); 
} 

现在,在这个地图我插入一个键(频道)和值。后来我试着和get()获得价值背部和运行这个调试代码,在我的情况下,给出了这样的输出:

getBValues - Given: Channel(...) 
getBValues - Contains Key: false <--- Doesnt contain key?! 
getBValues - Value: null <--- Null (bad) 
getBValues(key) - Equal: true <--- Given key and AMap key is equal 
getBValues(key) - HashCode Equal: true 
getBValues(key) - Key: Channel(Same...) 
getBValues(key) - Value: [] <--- Not null (This is the expected result) 

正如你所看到的,取出由HashMap中的键直接不工作,但我通过循环得到完全一样的密钥,这意味着它只能在get()找不到。我的问题是什么会造成这种情况? get()如何找不到存在的密钥?

我会提供一些这样的代码示例,但我似乎无法独立重现此。

有什么建议可能会导致这种情况?

+3

*“......我很确定是HashMap的错误”*。跟着我重复一遍。 “错误在**我的**代码中。” - http://storm.stackexchange.com/questions/1785/what-should-every-programmer-know-about-programming/1842#1842 – 2011-05-14 04:54:09

+0

@Stephen我的意思是更多的“在HashMap中的某些'功能'造成这个“ – TheLQ 2011-05-14 04:59:01

回答

4

从我所看到的,我们仍然没有排除,如果有做不变性。 如果你这样做:

aMap.put(key, value); 
key.setFieldIncludedInHashCodeAndEquals(25); 

那么你会得到上面的结果。

要在你的榜样排除这个可能性,无论是向我们展示更多的代码,或在for循环以上,加

System.out.println(aMap.get(entry.getKey())); 

此外,使用调试器。这样,你可以看到你的物体是否在正确的桶中。

+0

嗯......给了我一个空值。我猜hashCode在添加后会改变。我会看看我是否可以将我的代码更新为可行。 – TheLQ 2011-05-14 05:11:13

+0

因此,在将对象添加到地图后,是否有任何字段作为hashCode的一部分或等于您在地图中存储为键的对象时发生了变化? – Buhb 2011-05-14 05:14:02

+0

这就是为什么地图中的键必须是不可变的。 – duffymo 2011-05-14 13:55:05

8

我敢打赌,你没有在你的关键Channel类中正确地覆盖equals和hashCode。这将解释它。

约书亚·布洛克告诉你如何正确地做到这一点在他的“有效的Java”第3章

http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf

+0

我做过龙目岛项目,甚至在课堂上专门排除了2个影响平等的HashSet。 – TheLQ 2011-05-14 04:05:47

+0

我不知道龙目岛是什么,我无法分辨这是否意味着“是的,我有一个合适的equals和hashCode实现。”如果密钥是不可变的,那么最好。您的频道是否属实? – duffymo 2011-05-14 04:11:43

+1

在他特定的测试中,hashCode为密钥和存储密钥提供相同的值。它可能被错误地或正确地执行,但这个例子是正确的。 key.equals(entry.key)也是正确的。唯一剩下的原因是我可以看到entry.key.equals(key)是否为false。 – 2011-05-14 04:25:02