簡體   English   中英

如何迭代SortedSet來修改其中的項目

[英]How to iterate over a SortedSet to modify items within

我想說我有一個List。 在for循環中修改list的項目沒有問題:

for (int i = 0; i < list.size(); i++) { list.get(i).setId(i); }

但是我有一個SortedSet而不是list。 我怎么能用它呢? 謝謝

首先, Set假定它的元素是不可變的(實際上,可變元素允許的,但必須堅持一個非常具體的合同,我懷疑你的類一樣)。

這意味着通常您不能像使用列表那樣就地修改set元素。

Set支持的兩個基本操作是添加和刪除元素。 可以將修改視為刪除舊元素,然后添加新元素:

  1. 通過使用Iterator.remove() ;您可以在迭代時處理刪除。
  2. 您可以在單獨的容器中累積添加內容,並在末尾調用Set.addAll()

您無法修改set的密鑰,因為它會導致設置重新定位/重新排序。 因此,迭代將如何進一步運行將是未定義的行為。

您可以使用iterator.remove()刪除元素。 但是你不能添加元素,通常更好的解決方案是在新集合中累積它們並在迭代后添加它。

Set mySet = ...;
ArrayList newElems = new ArrayList();

for(final Iterator it = mySet.iterator(); it.hasNext(); )
{
  Object elem = it.next();
  if(...)
   newElems.add(...);
  else if(...)
   it.remove();
  ...
}
mySet.addAll(newElems);

您應該使用Iterator或更好的增強型for循環語法(這取決於實現Iterable接口的類),而不管您正在使用的Collection 這抽象出用於遍歷集合的機制,並允許替換新實現而不影響迭代例程。

例如:

Set<Foo> set = ...

// Enhanced for-loop syntax
for (Foo foo : set) {
 // ...
} 

// Iterator approach
Iterator it = set.iterator();
while (it.hasNext()) {
  Foo foo = it.next();
}

編輯

Kan對於修改項目的密鑰提出了一個很好的觀點。 假設你的類的equals()hashCode()方法完全基於“id”屬性(你正在改變),最安全的方法是在迭代時從Set顯式刪除它們並將它們添加到“輸出” “ Set ; 例如

SortedSet<Foo> input = ...
SortedSet<Foo> output = new TreeSet<Foo>();

Iterator<Foo> it = input.iterator();
while (it.hasNext()) {
  Foo foo = it.next();
  it.remove(); // Remove from input set before updating ID.
  foo.setId(1);
  output.add(foo); // Add to output set.
}

從Java 1.6開始,您就可以使用NavigableSet

你不能這樣做。 但你可能會嘗試,也許你會成功,也許你會得到ConcurrentModificationException 記住,在迭代時修改元素可能會產生意想不到的結果,這一點非常重要。 您應該在某些集合中收集這些元素。 在迭代之后逐個修改它們。

這只有在id不用於equals時才有效,或者用於排序集的comperator:

int counter = 0;
for(ElementFoo e : set) {
  e.setId(counter);
  couter++;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM