在 HashSet / HashMap 中修改对象的 hashCode

7

我是一个相对新手的Java开发者,下面的问题让我很疑惑:在设置内容之前,通常我会先将对象添加到一个ArrayList中。

List<Bla> list = new ArrayList<>();
Bla bla = new Bla();
list.add(bla);
bla.setContent(); // content influences hashCode

这种方法非常有效。我担心在与HashSetHashMap一起使用时,这种方法会给我带来麻烦。内部哈希表在添加对象时设置。如果在将对象添加到HashSetHashMap之后调用setContent()(并且其hashCode更改),会发生什么?
我应该在将对象添加/放入HashSetHashMap之前完全设置(影响hashCode的)内容吗?通常建议在添加对象之前完成构建吗?
非常感谢您的见解。

如果您可以使用 Map<String, Bla> map = new HashMap<>(),其中您将使用字符串标识符作为映射键,则即使值在之后更改,您也不应该有问题。 - Mick Mnemonic
1个回答

9
如果在对象添加到 HashSet 或 HashMap 后(其 hashCode 更改)调用 setContent(),会发生什么?
灾难。
我应该在将对象添加到 HashSets 或 HashMaps 之前完全设置(hashCode 影响)的内容吗?通常建议先完成构建对象后再添加它们吗?
是的。 文档中相关的行在java.util.Set上: 注意:如果可变对象用作集合元素,则必须非常小心。如果在对象作为集合中的元素时以影响 equals 比较的方式更改对象的值,则不指定集合的行为。这种禁止的特殊情况是,集合不能包含自身作为元素。
一般来说,此类错误将表现为元素既“在”又“不在”您的集合中,不同的方法会产生分歧。 您可能会很幸运,您的元素仍然可能出现在集合中,或者可能不会; 这可能随机发生。
这就是为什么大多数对象最好是不可变的——在构建后完全无法修改的众多原因之一。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接