在迭代HashSet时,是否可能覆盖一些元素(不一定是正在迭代的元素)。我想知道除了删除、编辑和再添加之外的方法。
我之所以这样问,是因为在迭代时使用remove总是会导致java.util.ConcurrentModificationException。我发现没有一个方法可以覆盖集合中的元素。
任何帮助都将不胜感激。
谢谢,
Somnath
在迭代HashSet时,是否可能覆盖一些元素(不一定是正在迭代的元素)。我想知道除了删除、编辑和再添加之外的方法。
我之所以这样问,是因为在迭代时使用remove总是会导致java.util.ConcurrentModificationException。我发现没有一个方法可以覆盖集合中的元素。
任何帮助都将不胜感激。
谢谢,
Somnath
Iterator
迭代并调用Itertator.remove()
来删除其中一个项,包括Set
的项,但这仅允许您删除迭代中的当前项。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);
}
}
// 我使用了Guava集合代码。但是这个操作也可以很简单地完成。
只需将set转换为List并使用{{link1:set()
}},完成后将其转换回Set
或者在迭代时维护另一个Set
无法实现。因为替换元素基本上是删除+插入。 这是一个集合,而不是列表。例如,集合{1,2}中有两个元素,您想用{2}替换{1}。这是不可能的,因为结果集不能包含{2,2} - 即两个相等的元素。