Java Map Implementation不基于HashCode

时间:2012-02-04 14:46:00

标签: java

是否有一些不使用HashCode的java.util.Map实现?

我有以下问题:

  1. 我在HashMap上存储与另一个对象关联的对象;
  2. 从步骤1中使用的密钥对象更改属性;
  3. 由于哈希码用于在HashMap的常规实现上存储密钥,当我在get()上执行HashMap时,我得到null,因为旧对象hashCode在步骤1中有所不同
  4. 有解决方案吗?或者我真的应该只使用不可变字段作为我的equals / hashCode方法吗?

7 个答案:

答案 0 :(得分:9)

IdentityHashMap使用Object标识而不是hashCode;但这确实意味着您需要用作键的原始对象来检索地图的值。其他选项是重新定义哈希码以排除对象的可变部分,或者 - 如果由于某种原因无法重新定义hashCode - 将对象包装在另一个提供稳定hashCode的对象中。

答案 1 :(得分:6)

建议您使用不可变密钥,并将密钥/值对重新插入Map,而不是在原位变更密钥。正如您所发现的,这只会导致奇怪的错误。

如果这不适合你,那么看看你是否可以忽略hashCode()方法中的mutable属性,这样哈希码就不会改变。但是,如果这是该课程的唯一属性,那不是一个好主意。

但是,它确实需要密钥的TreeMaphashCode()方法之间的一致性,因此如果这些方法的返回值可以更改,您可能会遇到与以前相同的问题。

答案 2 :(得分:1)

所有地图应使用不可变对象作为密钥。适用于Python;适用于Java。

如果仅使用不可变字段实现equals和hashCode,那么应该没问题。

答案 3 :(得分:0)

如果您不想要原始实施,请覆盖equalshashCode方法。

答案 4 :(得分:0)

所有关联容器都使用比较或哈希代码,因此我建议您使用equals() / hashCode()方法的不可变字段。

答案 5 :(得分:0)

如何再次删除和添加它?

在步骤2中,您可以删除步骤1中添加的元素,然后再次添加新的最新属性集。这样,当您尝试进入第3步时,您会找到它。

试试吧。

答案 6 :(得分:0)

我认为修改地图中的关键对象不是一个好习惯。

但如果您真的想要,可以覆盖hashCode()并记住覆盖equal()方法。