簡體   English   中英

如何在Java上進行迭代時覆蓋HashSet元素

[英]How to overwrite a HashSet element in Java while iterating over it

迭代時是否可以覆蓋某些HashSet元素(不一定是迭代的元素)。 我想知道除刪除,編輯然后重新添加之外的其他方法嗎? 我問這個原因是因為在迭代時使用remove總是會給出java.util.ConcurrentModificationException。 我發現沒有方法可以覆蓋set元素。

任何幫助將不勝感激。

謝謝,

頌歌

您可以從一個刪除一個項目Collection -包括一個Set -而遍歷它,只要你迭代它使用Iterator和調用Itertator.remove()做刪除。 但是,這僅允許您在迭代中刪除當前項目。

您不能刪除或添加另一個項目,因為這將導致ConcurrentModificationException ,因為如果更改Set則不清楚如何迭代它。

此外,與List不同,談論替換 Set的條目沒有任何意義。 List項具有定義順序,因此,例如,如果第二項是“ A”,則可以將其替換為“ B”。 Set項目沒有訂單,因此您不能直接用另一個替換它,您所能做的就是刪除舊的並添加新的。

完全取決於您要執行的操作,最好的方法可能是遍歷Set的副本:

Set<Object> originalSet = someMethod(); 

for (Object item : new HashSet<Object>(originalSet)) {
  //do stuff which modifies originalSet
}

但是,您必須考慮以下事實:您迭代的對象將是原始值,並且不會反映您所做的任何更改。

如果這樣做不可行,則可能有必要找到另一種方法來處理Set中的項目,而不必通過跟蹤已處理的節點來簡單地遍歷它們,從而有意義。

這樣的事情可能會做,但可能會有所改善,具體取決於您在做什么:

Set<Object> originalSet = somemethod();

//Keep track of items we've already processed
Set<Object> processed = new HashSet<Object>();

//toDo is used to calculate which items in originalSet aren't in processed
Set<Object> toDo = new HashSet(originalSet);
toDo.removeAll(processed);

while (! toDo.isEmpty()) {
  //Get an object from toDo
  Object item = toDo.iterator().next();

  //Do some processing
  //Can update originalSet or even remove from processed if we want to re-do an item

  //Recalculate what's left to do
  processed.add(item);
  toDo = new HashSet(originalSet);
  toDo.removeAll(processed);
}
Set<Key> set = Sets.newHashSet();
// ...

for (Key k : ImmutableSet.copyOf(set)) {
  if (needToMessWith(k)) {
    set.remove(k);
    k.mutateAsNeeded();
    set.add(k);
  }
}

//我使用了番石榴收集代碼。 沒有它就足夠簡單了。

只需將set轉換為List並使用set() ,一旦完成,將其轉換回Set

或在迭代時維護另一個Set

沒有辦法做到這一點。 因為替換元素基本上是刪除+插入。 這是一個集合,而不是列表。 例如,集合{1,2​​}中有兩個元素,而您想用{2}替換{1}。 這是不可能的,因為結果集不能包含{2,2}-即兩個相等的元素。

暫無
暫無

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

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