7

私は処理する必要があります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(ユーザー定義の正の整数)を下回ると、削除されます。また、マップに空のリストが含まれている場合、対応するキーが削除されます。

私は次のコードを使用しています:

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

また、これが効率的なコーディング方法であるかどうかもわかりませんか?マップには最大2000のエントリが含まれているため。お知らせ下さい。

4

2 に答える 2

1

が作成さConcurrentModificationExceptionれた後に基になるコレクションが変更され、その変更がそれ自体によって行われない場合に、 が発生する可能性があります。IteratorIterator

書かれているコードでは、それが発生する可能性のある場所は 1 つだけです。同じコレクションのイテレータである とit1の間の相互作用です。it2一方を呼び出すとremove、次に呼び出すときにもう一方が壊れますnext

これを回避するにはさまざまな方法がありますが、1 つの方法は、次のように、「キー」コレクションから削除するものをそのコレクションの反復から分離することです。

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()

于 2013-04-03T17:12:06.953 に答える
0

マップの内部構造の「ビュー」にすぎないため、マップの keySet で iterator.remove() を使用することはできません。

ただし、マップの entrySet() で反復子を使用できます。ここで、各要素は、マップするすべてのエントリ (キーと値のペア) を含む Map.Entry のインスタンスです。このイテレータで iterator.remove() を呼び出すと、対応するキーと値のペアがマップから効果的に削除されます。

Map<Integer, String> map = new HashMap<Integer, String>();
map.put(Integer.valueOf(0), "0");
map.put(Integer.valueOf(1), "1");
map.put(Integer.valueOf(2), "2");
map.put(Integer.valueOf(3), "3");
map.put(Integer.valueOf(4), "4");

System.out.println(map);

Iterator<Map.Entry<Integer, String>> entryIter = map.entrySet().iterator();
while (entryIter.hasNext()) {
   Map.Entry<Integer, String> entry = entryIter.next();
   if (entry.getKey().intValue() % 2 == 0)
       entryIter.remove();
}

System.out.println(map);

それが役立つことを願っています。

よろしく

于 2013-04-03T15:29:03.233 に答える