具有可变对象的 Java 集合
当对象可变时,TreeSet、HashSet 或 LinkedHashSet 的行为如何?我无法想象它们会在任何意义上发挥作用?
如果我在添加对象后修改它;该列表的行为是什么?
除了链表或数组之外,是否有更好的选择来处理可变对象的集合(我需要对其进行排序/索引/等)并每次简单地迭代它们?
How does a TreeSet, HashSet or LinkedHashSet behave when the objects are mutable? I cannot imagine that they would work in any sense?
If I modify an object after I have added it; what is the behaviour of the list?
Is there a better option for dealing with a collection of mutable objects (which I need to sort/index/etc) other than a linked list or an array and simply iterating through them each time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
设置
接口直接解决了这个问题:“注意:如果将可变对象用作集合元素,则必须格外小心。如果对象的值以影响等于比较的方式更改,而对象的更改则不会指定集合的行为是集合中的一个元素。此禁止的一个特殊情况是集合不允许将其自身包含为元素。”附录:
当尝试决定哪种集合实现最合适时,可能值得查看 核心集合接口。对于
设置
特别是实现,只要equals()
和hashCode()
正确实现,任何不相关的属性都可能是可变的。类比数据库关系,任何属性都可以改变,但主键必须是不可侵犯的。The
Set
interface addresses this issue directly: "Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element."Addendum:
When trying to decide which collection implementation is most suitable, it may be worth looking over the core collection interfaces. For
Set
implementations in particular, as long asequals()
andhashCode()
are implemented correctly, any unrelated attributes may be mutable. By analogy with a database relation, any attribute may change, but the primary key must be inviolate.如果对象的 hashCode 和比较方法的行为在插入后发生变化,则可变性只是集合的一个问题。
处理此问题的方法是从集合中删除对象,并在更改后重新添加它们,以便对象。
从本质上讲,从集合的角度来看,这会导致一个不可变的对象。
另一种性能较差的方法可能是保留一个包含所有对象的集合,并在需要对集合进行排序或索引时创建 TreeSet/HashSet。对于对象不断变化并且您同时需要访问地图的情况,这并不是真正的解决方案。
Being mutable is only a problem for the collection if the objects' hashCode and behaviour of compare methods change after it is inserted.
The way you could handle this is to remove the objects from the collection and re-adding them after such a change so that the object.
In essence this results in a inmutable object from the collections' point of view.
Another less performant way could be to keep a set containing all objects and creating a TreeSet/HashSet when you need the set to be sorted or indexed. This is no real solution for a situation where the objects change constantly and you need map access at the same time.
处理这种情况的“最佳”方法是保留辅助数据结构以供查找,有点像数据库中的索引。然后您的所有修改都需要确保索引已更新。很好的例子是映射或多重映射 - 在更新之前,从任何索引中删除条目,然后在更新之后将它们添加回新值。显然这需要注意并发性等。
The "best" way to deal with this situation is to keep ancillary data structures for lookup, a bit like indexes in a database. Then all of your modifications need to make sure the indexes are updated. Good examples would be maps or multimaps - before an update, remove the entry from any indexes, and then after an update add them back in with the new values. Obviously this needs care with concurrency etc.