なんとな~くしあわせ?の日記

「そしてそれゆえ、知識そのものが力である」 (Nam et ipsa scientia potestas est.) 〜 フランシス・ベーコン

Javaの拡張for文でConcurrentModificationException

拡張for文を多用した結果wwwwwww

反省のための記事

やろうとしたこと
  • for文の中でコレクションを回し条件に一致したものを削除・更新したい
  • 拡張for文ってJava SE 1.5でサポートされているので大して新しくないですね
結果
  • バグった
原因
  • スレッドセーフじゃないコレクションを回しているのにその中で変更を行ったため
対策
  • コレクションのコピーを用意してそいつをイテレーション、本体に削除・更新をした
  • 普通のfor文使って要素削除後に要素が空のものを削除、のほうがよかった
  • まあそれよか普通にIterator使いましょうという話ですね
関連

ConcurrentHashMapならばこの問題は発生しない

ConcurrentHashMapという選択 - 技術開発日記

ソース

import java.util.List;
import java.util.ArrayList;

public class prog {
    /**
     *
     * @param args - Arguments passed from the command line
     **/
    public static void main(String[] args) {

	List<String> strList = new ArrayList<String>();
	strList.add("a");
	strList.add("b");
	strList.add("c");

	System.out.println("=== Test1 ===");

	// trace
	for (String s : strList) {
	    System.out.println(s);
	}

	System.out.println("=== Test1 ===");

	// expect exception !
	try {

	    System.out.println("=== Test2 ===");

	    for (String s : strList) {

		if ( s.equals("a") ) {
		    strList.remove("a");
		} else {
		    System.out.println(s);
		}
	    }
	    
	} catch (Exception e) {
	    e.printStackTrace();
	    System.out.println("=== Test2 ===");
	}
    }
}