更改 HashSet / HashMap 内对象的 hashCode

dot*_*win 4 java arraylist hashmap hashcode hashset

我对 Java 比较陌生,对以下事情感到困惑:我通常ArrayList在设置内容之前向 an 添加对象。IE,

List<Bla> list = new ArrayList<>();
Bla bla = new Bla();
list.add(bla);
bla.setContent(); // content influences hashCode
Run Code Online (Sandbox Code Playgroud)

这种方法效果很好。我担心这种方法在与HashSets 或HashMaps一起使用时是否会给我带来麻烦。内部哈希表在添加对象时设置。如果setContent()在对象被添加到HashSetor HashMap(并且它的 hashCode 改变)之后被调用会发生什么?

添加/放入HashSets 或HashMaps之前,我应该完全设置(影响哈希码的)内容吗?通常是否建议在添加对象之前完成构建对象?

非常感谢您的见解。

Lou*_*man 6

如果在将对象添加到 HashSet 或 HashMap(及其 hashCode 更改)之后调用 setContent() 会发生什么?

灾难。

在添加/放入 HashSets 或 HashMaps 之前,我是否应该完全设置(影响 hashCode 的)内容?通常是否建议在添加对象之前完成构建对象?

是的。

相关的文档行位于java.util.Set

注意:如果将可变对象用作集合元素,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是集合中的元素,则不会指定集合的​​行为。此禁止的一个特殊情况是不允许集合将自身包含为元素。

一般来说,这种错误会表现在元素“在”和“不在”你的集合中,不同的方法不一致。你可能很幸运,你的元素可能看起来仍然在集合中,或者可能没有;这可能基本上是随机发生的。

这是为什么大多数对象都是不可变的最佳实践的众多原因之一 - 在构造之后首先完全不可能修改。