1

HashMap の要素と比較して、以下のコードのキーと値のペアを削除するにはどうすればよいですか?

Map<BigDecimal, TransactionLogDTO> transactionLogMap = new HashMap<BigDecimal, TransactionLogDTO>();
for (BigDecimal regionID : regionIdList) {// Generation new logDTO
                                            // objects for each in scope
                                            // region
    transactionLogMap.put(regionID, new TransactionLogDTO());
}
Set<BigDecimal> inScopeActiveRegionIdSet = new HashSet<BigDecimal>();

for (PersonDTO personDTO4 : activePersons) {

    inScopeActiveRegionIdSet.add(personDTO4.getRegion());

}

for (BigDecimal bigDecimal : transactionLogMap.keySet()) {
    if (!inScopeActiveRegionIdSet.contains(bigDecimal)) {
        transactionLogMap.remove(bigDecimal);
    }
}
4

4 に答える 4

8

javadocに従って

ConcurrentModificationExceptionは、そのような変更が許可されていない場合に、オブジェクトの同時変更を検出したメソッドによってスローされる場合があります。

 transactionLogMap.remove(bigDecimal);

for loop使用する代わりにIterator、イテレータで remove を呼び出します。

例:

Iterator iter = transactionLogMap.keySet().iterator();
while(iter.hasNext())
{
iter.remove();
}

また

ConcurrentHashMap の使用を検討してください。

注: コードで入力し、参照として使用してください。構文エラーがある可能性があります。

于 2012-07-30T14:04:58.470 に答える
4

問題はこれらの行にあります

for (BigDecimal bigDecimal : transactionLogMap.keySet()) {
    if(!inScopeActiveRegionIdSet.contains(bigDecimal)) {
        transactionLogMap.remove(bigDecimal);
    }
}

を呼び出すときに基にtransactionLogMapなるものを直接変更しながら、 を反復処理していますが、拡張 for ループはそれらの変更を認識できないため、これは許可されていません。CollectiontransactionLogMap.remove

正しい解決策は、次を使用することIteratorです。

Iterator<BigDecimal> it = transactionLogMap.keySet().iterator();//changed for syntax correctness
while (it.hasNext()) {
    BigDecimal bigDecimal = it.next();
    if(!inScopeActiveRegionIdSet.contains(bigDecimal)) {
        it.remove();
    }
}
于 2012-07-30T14:08:29.010 に答える
2

コレクションを繰り返し処理している間は、コレクションからアイテムを削除することはできません。これにより、取得している例外が発生します。

電話すると:

for(TypeX x: collectionOfX){ ... }

内部で何が起こるかというと、collectionOfX の反復子を作成し、サイクルから明示的に中断するか、反復子の hasNext() が false になるまで反復します。

反復中にコレクションからアイテムを削除する必要がある場合は、そのforeach構成を Iterator への明示的な呼び出しに置き換える必要があります。何かのようなもの:

Iterator<BigDecimal> iter = transactionLogMap.keySet().iterator();
while(iter.hasNext()) {
   BigDecimal bDecimal = iter.next();
   ...
   iter.remove(); //this will remove the current item from the collection, without raising an exception.
}
于 2012-07-30T14:09:12.637 に答える
0

または、 のサイズが小さい場合inScopeActiveRegionIdSetは、代わりに反復する方が短くて速い可能性があります。

for (BigDecimal bigDecimal : inScopeActiveRegionIdSet) {
    transactionLogMap.remove(bigDecimal);
}
于 2012-07-30T14:18:28.287 に答える