2013-08-06 3 views
1

У меня есть код ниже, но я получаю ConcurrentModificationException, как мне избежать этой проблемы? (Я должен использовать WeakHashMap по какой-то причине)ConcurrentModificationException с WeakHashMap

WeakHashMap<String, Object> data = new WeakHashMap<String, Object>(); 

// some initialization code for data 

    for (String key : data.keySet()) { 
     if (data.get(key) != null && data.get(key).equals(value)) { 
      //do something to modify the key 
     } 
    } 
+0

Возможный дубликат [Итерация по коллекции, исключая ConcurrentModificationException при удалении в цикле] (http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re) – Raedwald

ответ

-1

Вероятно потому, что ваш // do something в итерации фактически изменяя основную коллекцию.

От ConcurrentModificationException:

Например, если поток изменяет коллекцию непосредственно в то время как итерация по коллекции с отказоустойчивостью быстрым итератором, итератор выбросит это исключение.

И от (Weak)HashMap's keySet():

Возвращает представление набора ключей, содержащихся в этой карте. Набор поддерживается картой, поэтому изменения в карте отражаются в наборе и наоборот. Если карта изменена, когда выполняется итерация по множеству (за исключением операции собственного удаления итератора), результаты итерации не определены.

+0

yes , Ты прав! Я должен обновить ключ во время итерации набора ключей, так есть ли обходной путь к этой проблеме, если мне еще нужно использовать WeakHashMap? Благодарю. –

+0

Могу ли я клонировать data.keyset() и повторять этот клонированный набор, изменяя ключ исходных данных? –

+1

Да, это определенно один из способов сделать это. – Aert

0

Записи WeakHashMap автоматически удаляются, когда обычное использование ключа больше не реализуется, это может происходить в другом потоке. При клонировании keySet() в другой Set параллельный поток может удалять записи тем временем, в этом случае ConcurrentModificationException будет выброшен на 100%! Вы должны синхронизировать клонирование.

Пример:

Collections.synchronizedMap(data); 

Пожалуйста, обратите внимание, что

Collections.synchronizedSet(data.keySet()); 

Может не быть использован, поскольку data.keySet() полагаться на экземпляре Дейтов который не синхронизирован здесь! Более подробно: synchronize (keySet) предотвращает выполнение методов на keySet, но метод removeStyle keySet никогда не вызывается, но метод remove WeakHashMap вызывается так, что вам нужно синхронизировать с WeakHashMap!

Смежные вопросы