Java,集合上的多个迭代器,删除正确的子集和ConcurrentModificationException
我有一个集合a={(1,2),(1,2,3),(2,3,4),(3,4),(1)}
我想把它变成A={(1,2,3),(2,3,4)},从这个集合中去掉适当的子集
我使用一个HashSet来实现这个集合,使用2迭代器来运行这个集合,并使用containsAll(c)检查所有对的正确子集条件,使用remove()方法来删除正确的子集
代码如下所示:
HashSet<Integer> hs....
Set<Integer> c=hs.values();
Iterator<Integer> it= c.iterator();
while(it.hasNext())
{
p=it.next();
Iterator<Integer> it2= c.iterator();
while(it2.hasNext())
{
q=it2.next();
if q is a subset of p
it2.remove();
else if p is a subset of q
{
it.remove();
break;
}
}
}
我第一次从内部while循环中出来并执行
p=it.next();
当在集合上迭代时修改集合时会出现异常。但这就是问题所在。remove()用于
我在仅使用1个迭代器时使用了remove(),在那里没有遇到任何问题
如果异常是因为我在迭代时从“c”或“hs”中删除了一个元素,那么当它遇到下一个元素时,应该抛出异常。next()命令,但我没有看到它。我看到它时,它遇到了它。next()命令
我使用了调试器,在删除元素后,集合和迭代器处于完美的顺序。它们包含并指向正确的更新集和元素。信息技术next()包含要分析的下一个元素,它不是已删除的元素
关于如何在提交更新之前不复制hashset本身并将其用作中介的情况下执行我正在尝试的操作,有什么想法吗
多谢各位
# 1 楼答案
ConcurrentModificationException
背后的思想是维护迭代器的内部状态。当您从一组项目中添加或删除内容时,即使没有出现任何错误,它也会引发异常。这是为了避免编码错误,这些错误最终会在平常的代码中抛出NullPointerException
。除非您有非常有限的空间限制或有一个非常大的集合,否则您应该只制作一个工作副本,您可以在其中添加和删除而不必担心# 2 楼答案
无法使用
it2
修改集合,并继续使用it
对其进行迭代。正如异常所说,它是并发修改,不受支持恐怕你只能选择中间系列了
编辑
实际上,您的代码似乎没有意义:您确定它是
Integer
的集合而不是Set<Integer>
的集合吗?在您的代码中p
和q
是Integer
,因此“如果q是p的子集”似乎没有太多意义有一个明显的方法可以让这一点变得更聪明:首先按大小对集合进行排序,当你从最大的集合到最小的集合时,将你想要保留的集合添加到一个新的列表中。您只需对照
keep
列表检查每个集合,而不必检查整个原始集合# 3 楼答案
创建另一个包含要删除的所有子集的集合subsetNeedRemoved如何?对于每个子集,如果有适当的超集,则将子集添加到subsetNeedRemoved。最后,可以在subsetNeedRemoved上循环,并删除原始集中的相应子集
# 4 楼答案
我会写这样的东西
是的,它会消耗一些额外的内存,但它是惯用的、直截了当的,并且可能比另一种方法更快