• このエントリーをはてなブックマークに追加

スポンサードリンク

はじめに

ConcurrentModificationException が Java で発生したときの対処方法.

以下のようなコードを実行すると, 例外発生.

import java.util.Set;
import java.util.HashSet;

public class ConcurrentModification {
	public static void main (String[] args) {
		Set<Integer> set = new HashSet<Integer>();
		for (int i = 0; i < 5; i++)
			set.add (i);

		for (Integer i: set) {
			if (i == 3) {
				set.remove (i);
			}
		}
	}
}
&#91;/sourcecode&#93;

&#91;sourcecode language="bash" title="" &#93;
 Exception in thread "main" java.util.ConcurrentModificationException
 	at java.util.HashMap$HashIterator.nextEntry (HashMap.java:922)
 	at java.util.HashMap$KeyIterator.next (HashMap.java:956)
 	at ConcurrentModification.main (ConcurrentModification.java:10)
&#91;/sourcecode&#93;

<p> 原因は, iterater で for 文を回している時に, 要素を削除しようとしたから. </p>

<ul class="org-ul">
<li><a href="http://e-class.center.yuge.ac.jp/jdk_docs/ja/api/java/util/ConcurrentModificationException.html">ConcurrentModificationException (Java Platform SE 6)</a>
</li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-2" class="outline-2">
<h2 id="unnumbered-2">回避方法</h2>
<div class="outline-text-2" id="text-unnumbered-2">
</div><div id="outline-container-unnumbered-3" class="outline-3">
<h3 id="unnumbered-3">その 1: イテレータを利用しない</h3>
<div class="outline-text-3" id="text-unnumbered-3">
<p> イテレータなんてつかってかっこつけているのが悪い. Index で for 文をまわす </p>


for (int i=0; i < set.size (); i++) {
	if (i == 3) {
		set.remove (i);
	}
}
&#91;/sourcecode&#93;
</div>
</div>

<div id="outline-container-unnumbered-4" class="outline-3">
<h3 id="unnumbered-4">その 2 Concurrent ライブラリを利用する</h3>
<div class="outline-text-3" id="text-unnumbered-4">
<p> ConcurrentHashMap を利用する. ただし, ConcurrentHashSet はない&#x2026;以下のように対応 </p>


Set<Integer> set = Collections.newSetFromMap (new ConcurrentHashMap<Integer, Boolean>());

その 3 コレクションをコピーして回す

すこし冗長か?

		Set<Integer> set = new HashSet<Integer>();
		for (int i = 0; i < 5; i++)
			set.add (i);

		Set<Integer> set2 = new HashSet<Integer>();
		set2.addAll (set);

		for (Integer i: set2) {
			if (i == 3) {
				set.remove (i);
			}
		}