當對象可變時,TreeSet,HashSet或LinkedHashSet如何運作?我無法想象他們會在任何意義上工作?具有可變對象的Java集合
如果我在添加對象後修改對象;列表的行爲是什麼?
是否有更好的選擇來處理可變對象集合(我需要排序/索引/等),而不是鏈接列表或數組,並且每次只遍歷它們?
當對象可變時,TreeSet,HashSet或LinkedHashSet如何運作?我無法想象他們會在任何意義上工作?具有可變對象的Java集合
如果我在添加對象後修改對象;列表的行爲是什麼?
是否有更好的選擇來處理可變對象集合(我需要排序/索引/等),而不是鏈接列表或數組,並且每次只遍歷它們?
Set
接口直接解決了這個問題:「注意:如果將可變對象用作集合元素,必須非常小心。如果對象的值以影響方式更改,則不會指定集合的行爲等於比較,而對象是集合中的一個元素,這種禁止的一個特例是不允許集合包含它自己作爲一個元素。「
附錄:
是否有處理可變對象的集合一個更好的選擇?
當試圖確定哪個集合實現最適合時,可能需要查看core collection interfaces。特別是對於Set
實現,只要equals()
和hashCode()
正確實現,任何不相關的屬性可能是可變的。通過與數據庫關係類比,任何屬性都可能發生變化,但主鍵必須是不可侵犯的。
如果對象的hashCode和比較方法的行爲在插入後發生更改,那麼存在可變只是集合的問題。
你可以處理這個問題的方法是從集合中刪除對象,並在這樣的變化之後重新添加它們以便對象。
從本質上講,這會導致從集合的角度來看不可變對象。
另一個性能較低的方法可能是保持包含所有對象的集合,並在需要對集合進行排序或索引時創建TreeSet/HashSet。對於對象不斷變化並且需要同時訪問地圖的情況,這不是真正的解決方案。
處理這種情況的「最佳」方法是保持查找的輔助數據結構,有點像數據庫中的索引。然後,所有修改都需要確保索引已更新。好的例子是map或multimaps - 在更新之前,從任何索引中刪除條目,然後在更新之後將它們添加回新值。顯然這需要注意併發等。