即使字符串和哈希代码不同,Java Hashtable.containsKey(字符串键)也会返回true。。。怎么用?

即使字符串和哈希代码不同,Java Hashtable.containsKey(字符串键)也会返回true。。。怎么用?,java,string,key,hashtable,hashcode,Java,String,Key,Hashtable,Hashcode,我目前在java中的哈希表有一些问题,FEightPuzzle是我创建的一个类 在我的类中,我有一个字符串,用于存储每个实例的键。现在,在我的程序中,当我在哈希表中检查重复的实例时,我有时会“找到”一些实例,而实际上找到的实例是不同的 举个例子,当我调用bol.containsKey(current.key)时,其中bol是一个HT,current是一个fiightpuzzle 如果这是真的,我检查键的值,它们是 current.key = "8 14 11 0 6 12 13 1 10 4 5

我目前在java中的哈希表有一些问题,FEightPuzzle是我创建的一个类

在我的类中,我有一个字符串,用于存储每个实例的键。现在,在我的程序中,当我在哈希表中检查重复的实例时,我有时会“找到”一些实例,而实际上找到的实例是不同的

举个例子,当我调用bol.containsKey(current.key)时,其中bol是一个HT,current是一个fiightpuzzle

如果这是真的,我检查键的值,它们是

current.key =
"8 14 11 0 6 12 13 1 10 4 5 9 15 2 3 7"

bol.get(current.key).key =
"12 8 4 0 13 9 5 1 14 10 6 2 15 11 7 3"
有价值

current.key.hashCode() = -950607924

bol.get(current.key).key.hashCode() = -1856769042

很抱歉打扰你,但这个问题真的困扰着我,老实说,这是我今晚最不希望发生的事情(你不喜欢这个)。。。任何提示或答案都将不胜感激

我重读了你的问题,据我所知,你有以下问题:

是吗

bol.containsKey(current.key)
检查
当前
是否已在
bol

当它返回true时,您希望由
current.key
映射到的值确实应该是
current
,但正如您的哈希代码所示,它不是

问题可能是以下之一:

  • 首先,您没有将拼图对象正确地放在哈希表中

    你应该这样做

    bol.put(somePuzzle.key, somePuzzle)
    
  • 当拼图出现在地图上时,你换了钥匙。这是不允许的

    在映射中添加条目后,如果不删除/重新插入映射,则不能更改密钥。

    哈希表将根据插入时提供的键查找对象

  • 您意外地为多个不同的拼图对象提供了相同的键(在这种情况下,一个
    put
    将覆盖上一个)



  • 一个建议是让FEightPuzzle覆盖hashCode和equals,并使用HashSet而不是Hashtable。

    我想你可能误解了Hashtable的功能。它将键映射到值。因此,在键上调用
    get(key)
    将返回您提供的值
    put(key,value)
    。现在,如果您总是将相同的值作为键输入,那么您应该期望得到相同的结果,但是在这种情况下,您只需要一个
    哈希集
    。如果您为不同的键输入相同的值,它将允许这样做。只有键在
    Hashtable
    中是唯一的(并且
    HashMap
    是相同的)。

    作为旁注,
    Hashtable
    已经过时,最好使用
    HashMap
    (或者
    ConcurrentHashMap
    ,如果需要线程安全性)。是否可能正在更改已添加到映射中的项的键(无需删除和重新添加它们以保持地图完整性)好问题,但不,我不认为这是可能的。实例的状态是在初始化时设置的,从那时起不会做任何更改-这就是密钥的位置。你可以在将对象添加到HT的位置发布代码吗?而且我以前输入错了,现在已经修复了,这些是来自实际密钥的值。FaightPuzzle-toString满足了hod与此完全不同。我仔细观察了一下,他们说java HT使用一个键,但对于相同的键,额外的对象是带扣的,就像一个键可以使用数组或链表指向多个对象一样。问题是,这与java HT api中描述的内容没有任何意义,因为他们明确指出每个键都应该唯一地映射到一个对象。我发现发生这种情况的唯一原因是当我导出列表并尝试将它们全部重新输入HT时,HT只填充了一半(我假设)正在覆盖具有相同键的旧对象…哦,天哪,我在HT中输入的第一个值似乎使用了错误的键。非常感谢您指出…HT中有200000多个对象,这只是第一个给我错误的对象。谢谢,这让我松了一口气。@Sekm:不,哈希表不允许同一个密钥有多个值。使用链表的bucketing仅用于具有相同哈希代码的不同密钥(或碰巧映射到同一个bucket的不同哈希代码)。@Paŭlo Ebermann这让事情更清楚了,感谢您的解释-我想知道在这些情况下会发生什么(因为哈希代码似乎存储为整数),我认为在这些情况下,equals方法将用于获得100%的准确度?不,我明白,我只是在第一次发布问题时输入了错误,很抱歉,这是我的错误啊,我明白了。因此,看起来您将密钥存储为值对象的一个成员?您是否可能重复使用这些值对象并为另一个键使用的ame实例?如果您可以包含一些代码片段,这里的人可能会提供帮助。