Java集合与可变对象

9

当对象是可变的时,TreeSet、HashSet或LinkedHashSet会如何表现?我无法想象它们会以任何方式工作?

如果在添加对象后修改对象,列表的行为是什么?

除了使用链表或数组并每次迭代进行操作之外,是否有更好的选项来处理可变对象的集合(需要排序/索引等)?

3个回答

4

Set接口直接解决了这个问题:“注意:如果可变对象用作set元素,则必须非常小心。如果在对象作为set元素时以影响equals比较的方式更改对象的值,则不会指定set的行为。此禁令的一个特例是,set不能包含自身作为元素。”

补充:

有没有更好的方法来处理可变对象的集合?

当尝试确定哪种集合实现最适合时,可以查看核心集合接口。对于特别是Set实现,只要正确实现equals()hashCode(),任何不相关的属性都可能是可变的。类比数据库关系,任何属性都可以更改,但主键必须不可违反。


2

如果集合中的对象在插入后其hashCode和比较方法的行为发生更改,那么可变性只影响集合本身。

应对这种情况的方法是从集合中删除对象,并在更改后重新添加它们,以便对象从集合的角度看是不可变的。

另一种不太高效的方法是保持一个包含所有对象的集合,并在需要将集合排序或索引时创建TreeSet/HashSet。这并不是一个真正的解决方案,当对象经常更改且需要同时进行映射访问时。


0
处理这种情况的“最佳”方法是保留辅助数据结构进行查找,有点像数据库中的索引。然后,所有修改都需要确保更新索引。好的例子是映射或多重映射 - 在更新之前,从任何索引中删除条目,然后在更新后使用新值将它们添加回去。显然,这需要注意并发等方面的问题。

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