自定义密钥对象应该是不可变的吗?如果是,那为什么呢?

时间:2012-08-22 06:33:00

标签: java collections immutability

好的我想在我的HashMap中将自定义用户定义的对象作为键,而不是说String。候选对象应该是不可变的吗?我在某处读到最好的做法是让它们不变,但我无法弄清楚原因。

3 个答案:

答案 0 :(得分:6)

如果你在HashMap中有一个可变键,那么它最终将会出现在错误的存储桶中,这会完全打破Map。

  1. 插入密钥,调用hashCode(),分配存储桶
  2. 更改密钥,hashCode更改,不再匹配存储桶
  3. 按(新)键查找,hashCode()导致错误的存储桶,找不到值
  4. 通过(旧)键查找,hashCode()导致“正确”的桶,但现在找到的键不再是equal(因为它现在是“新”键),所以它也被丢弃了
  5. 如果你在TreeMap中有一个可变键,那么它将最终位于树的错误位置,该位应该被排序(并且在插入时发生)。与上述基本相同。

    由于我们喜欢这里的明喻,这就像在现有的电话簿中用魔术标记更改你的名字而不打印一本新书:所以你的新名字“Smith”仍将列在“John”和“Johnston”之间“(没有人会寻找它),没有人会在”智能“和”史密瑟斯“(他们正在寻找它)之间找到它。 TreeMap就像电话簿一样工作。

答案 1 :(得分:5)

是的,它们应该是不可变的,因为如果它们可以改变它们将不能很好地作为键。想象一下,为你的房子买一个锁和钥匙,然后决定你想把钥匙打成不同的形状,让钥匙更漂亮。这不会很好,是吗?同样的原则适用于此。

答案 2 :(得分:0)

是。如果您从其他地方更新密钥,则无法再查找为该密钥存储的值。