在迭代它时从java中的集合中删除项目 [英] Removing items from a collection in java while iterating over it

查看:20
本文介绍了在迭代它时从java中的集合中删除项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够在迭代时从集合中删除多个元素.最初,我希望迭代器足够聪明,可以让下面的简单解决方案发挥作用.

I want to be able to remove multiple elements from a set while I am iterating over it. Initially I hoped that iterators were smart enough for the naive solution below to work.

Set<SomeClass> set = new HashSet<SomeClass>();
fillSet(set);
Iterator<SomeClass> it = set.iterator();
while (it.hasNext()) {
    set.removeAll(setOfElementsToRemove(it.next()));
}

但这会抛出一个ConcurrentModificationException.

请注意,就我所见, iterator.remove() 不会起作用,因为我需要一次删除多个内容.还假设无法确定要即时"删除哪些元素,但可以编写方法 setOfElementsToRemove().在我的特定情况下,它会占用大量内存和处理时间来确定迭代时要删除的内容.由于内存限制,也无法进行复制.

Note that iterator.remove() will not work as far as I can see because I need to remove multiple things at a time. Also assume that it is not possible to identify which elements to remove "on the fly", but it is possible to write the method setOfElementsToRemove(). In my specific case it would take up a lot of memory and processing time to determine what to remove while iterating. Making copies is also not possible because of memory constraints.

setOfElementsToRemove() 将生成一些我想要删除的 SomeClass 实例集,并且 fillSet(set) 将用条目填充该集.

setOfElementsToRemove() will generate some set of SomeClass instances that I want to remove, and fillSet(set) will fill the set with entries.

在搜索 Stack Overflow 后,我找不到解决这个问题的好方法,但几个小时后我意识到以下方法可以解决这个问题.

After searching Stack Overflow I could not find a good solution to this problem but a few hours break later I realized the following would do the job.

Set<SomeClass> set = new HashSet<SomeClass>();
Set<SomeClass> outputSet = new HashSet<SomeClass>();
fillSet(set);
while (!set.isEmpty()) {
    Iterator<SomeClass> it = set.iterator();
    SomeClass instance = it.next();
    outputSet.add(instance);
    set.removeAll(setOfElementsToRemoveIncludingThePassedValue(instance));
}

setOfElementsToRemoveInducingThePassedValue() 将生成一组要移除的元素,其中包括传递给它的值.我们需要删除传递的值,以便 set 为空.

setOfElementsToRemoveIncludingThePassedValue() will generate a set of elements to remove that includes the value passed to it. We need to remove the passed value so set will empty.

我的问题是是否有人有更好的方法来执行此操作,或者是否有支持此类删除的收集操作.

My question is whether anyone has a better way of doing this or whether there are collection operations that support these kind of removals.

另外,我想我会发布我的解决方案,因为似乎有需要,而且我想贡献 Stack Overflow 的优秀资源.

Also, I thought I would post my solution because there seems to be a need and I wanted to contribute the the excellent resource that is Stack Overflow.

推荐答案

通常,当您在循环遍历集合时从集合中删除元素时,您会得到一个 并发修改异常.这就是 Iterator 接口具有删除()方法.使用迭代器是在遍历元素集合时修改元素集合的唯一安全方法.

Normally when you remove an element from a collection while looping over the collection, you'll get a Concurrent Modification Exception. This is partially why the Iterator interface has a remove() method. Using an iterator is the only safe way to modify a collection of elements while traversing them.

代码如下:

Set<SomeClass> set = new HashSet<SomeClass>();
fillSet(set);
Iterator<SomeClass> setIterator = set.iterator();
while (setIterator.hasNext()) {
    SomeClass currentElement = setIterator.next();
    if (setOfElementsToRemove(currentElement).size() > 0) {
        setIterator.remove();
    }
}

这样您就可以安全地从 setOfElementsToRemove() 中删除所有生成删除集的元素.

This way you'll safely remove all elements that generate a removal set from your setOfElementsToRemove().

编辑

根据对另一个答案的评论,这可能更符合您的要求:

Based on a comment to another answer, this may be more what you want:

Set<SomeClass> set = new HashSet<SomeClass>();
Set<SomeClass> removalSet = new HashSet<SomeClass>();
fillSet(set);

for (SomeClass currentElement : set) {
    removalSet.addAll(setOfElementsToRemove(currentElement);
}

set.removeAll(removalSet);

这篇关于在迭代它时从java中的集合中删除项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆