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

Gee*_*eek 0 java collections immutability

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

Thi*_*ilo 6

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

  1. 插入密钥,调用hashCode(),分配存储桶
  2. 更改密钥,hashCode更改,不再匹配存储桶
  3. 查找(新)键,hashCode()导致错误的存储桶,找不到值
  4. 通过(旧)键查找,hashCode()导致"正确"的桶,但现在找到的键不再存在equal(因为它现在是"新"键),所以它也被丢弃

如果你在TreeMap中有一个可变键,那么它将最终位于树的错误位置,该位应该被排序(并且在插入时发生).基本上与上面相同.

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


Hov*_*els 5

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