gpt4 book ai didi

java - 如何在没有 ConcurrentModificationException 的情况下在 Java 中保留两个迭代器并删除它们之间的键

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:36:22 25 4
gpt4 key购买 nike

我必须处理 Map <BitSet,List<List<Integer>> MyMap

if (key1 contains all of corresponding true bits of key2)
Remove from key2 all those values which are common with key1)

在此过程中,如果列表中的元素数量低于 THRESHOLD(用户定义的正整数),则会将其删除。此外,如果 Map 包含空列表,则相应的键将被删除。

我正在使用以下代码:

List<BitSet> keys = new ArrayList<>(MyMap.keySet());  
ListIterator it1=keys.listIterator();
while(it1.hasNext()) {
BitSet key1=(BitSet)it1.next();
ListIterator it2=keys.listIterator(it1.nextIndex());
while(it2.hasNext()) {
BitSet key2=(BitSet)it2.next();
BitSet ankey=(BitSet)key1.clone();
ankey.and(key2);
if(ankey.equals(key1)) {//key1 is subset and key2 is superset
if(removePoints(key1,key2)) {
it1.remove();
break;
}
}
else if(ankey.equals(key2)) {
if(removePoints(key2,key1)) {
it2.remove();
}
}
}
}

public static boolean removePoints(BitSet key1,BitSet key2)
{
List<List<Integer>> list1=MyMap.get(key1);
List<List<Integer>> list2=MyMap.get(key2);
Boolean ret=false;
for(int i=0;i<list1.size();i++) {
List<Integer> sublist1=list1.get(i);
for(int j=0;j<list2.size();j++) {
List<Integer> sublist2=list2.get(j);
sublist1.removeAll(sublist2);
if(sublist1.isEmpty())
break;
}
if(sublist1.size()<=THRESHOLD)
list1.remove(sublist1);
if( list1.isEmpty()) {
MyMap.remove(key1);
ret=true;
}
}
return ret;
}

但是程序报错:

java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification
at java.util.ArrayList$Itr.next

此外,我不确定这是否是有效的编码方式?由于 map 包含约 2000 个条目。请指教。

最佳答案

ConcurrentModificationException 可能会在创建 Iterator 之后修改基础集合时发生,并且该修改不是通过 Iterator 完成的本身。

在您编写的代码中,只有一个地方会发生这种情况:it1it2 之间的交互,它们是同一集合上的迭代器。任何时候你在一个上调用 remove,另一个会在你下次调用 next 时中断。

有多种方法可以解决此问题,但一种方法是将要从“关键”集合中删除的内容与该集合的迭代分开,如下所示:

List<BitSet> allKeys = new ArrayList<>(MyMap.keySet());  
List<BitSet> removedKeys = new ArrayList<>();

for (ListIterator<BitSet> it1 = allKeys.listIterator(); it1.hasNext(); ) {
BitSet key1 = it1.next();
for (ListIterator<BitSet> it2 = allKeys.listIterator(it1.nextIndex()); it2.hasNext(); ) {
BitSet key2 = it2.next();
BitSet ankey=(BitSet)key1.clone();
ankey.and(key2);
if(ankey.equals(key1)) {//key1 is subset and key2 is superset
if(removePoints(key1,key2)) {
removedKeys.add(key1);
break;
}
}
else if(ankey.equals(key2)) {
if(removePoints(key2,key1)) {
removedKeys.add(key2);
break;
}
}
}
}

allKeys.removeAll(removedKeys);

allKeys 将处于您期望的状态。我假设稍后您会想要调用 MyMap.keySet().retainAll() 或类似的方法。

关于java - 如何在没有 ConcurrentModificationException 的情况下在 Java 中保留两个迭代器并删除它们之间的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15333682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com