![](/img/trans.png)
[英]Is iterating through a TreeSet slower than iterating through a HashSet in Java?
[英]Iterating through a TreeSet in java and updating it
我在Java中有一個TreeSet
,我有自己的比較器函數用於這個樹集。 現在我使用descendingIterator()
方法遍歷此樹集並更改元素。 那么這會更新實際樹集以及使用我的自定義比較器排序的方式嗎? 或者我是否需要刪除元素並放回更新的元素?
您需要刪除元素並將其添加回來。 通過將元素與其他元素進行比較,在插入元素時決定樹中元素的位置。 如果更改對象以便與其他元素進行比較更改,則必須先刪除元素,然后更改它,然后重新添加。
請注意,迭代時刪除元素只能使用迭代器的remove方法。 如果沒有獲得ConcurrentModificationException,AFAIK,您將無法在迭代期間添加它。 因此,一旦迭代結束,將其存儲在要重新添加到集合的元素列表中。
如果修改作為“鍵”一部分的對象的任何部分(由自定義比較器定義),則需要刪除並重新插入樹集的對象以“學習”有關更改的內容。 在迭代時你不應該這樣做:一個好的方法是收集需要在一個循環中更改的項目,然后在另一個循環中修改並重新插入它們。
作為一般的經驗法則,不建議“修改”添加到依賴於相等,哈希碼等的Java容器的任何值類型,因為沒有任何已知的標准容器執行自動平衡或調整以響應價值觀的變化(這是有道理的)。
與Set
,此規則對Map
類型同樣有效。 如果您在地圖上迭代並在原地修改“密鑰”,那么事情就會變得糟糕。 這就是為什么建議將不可變類型作為Map鍵(考慮String
, Integer
等)的原因。您可以通過一個簡單的示例來演示您的案例:
public class Test {
public static void main(final String[] args) {
Mutable m1 = new Mutable(1);
Mutable m2 = new Mutable(2);
Mutable m3 = new Mutable(3);
Mutable m4 = new Mutable(4);
TreeSet<Mutable> ts = new TreeSet<Mutable>(new Cmp());
ts.add(m1); ts.add(m2); ts.add(m3); ts.add(m4);
System.out.println(ts);
for (Iterator<Mutable> iter = ts.iterator(); iter.hasNext(); ) {
Mutable m = iter.next();
if (m.i == 1 || m.i == 3) {
m.i = m.i + 10;
}
}
System.out.println(ts);
}
}
class Mutable {
public int i;
public Mutable(int i) {
this.i = i;
}
public String toString() {
return "Mutable[" + i + "]";
}
}
class Cmp implements Comparator<Mutable> {
@Override public int compare(Mutable o1, Mutable o2) {
return Integer.valueOf(o1.i).compareTo(Integer.valueOf(o2.i));
}
}
Output:
[Mutable[1], Mutable[2], Mutable[3], Mutable[4]]
[Mutable[11], Mutable[2], Mutable[13], Mutable[4]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.