preloader
學習

Java的HashMap concurrentModificationException

http://stackoverflow.com/questions/85190/how-does-the-java-for-each-loop-work

引用此頁的資料

for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {  
  String item = i.next();  
  System.out.println(item);
}

Note that if you need to use i.remove(); in your loop, or access the actual iterator in some way, you cannot use the for( : ) idiom, since the actual Iterator is merely inferred.

As was noted by Denis Bueno, this code works for any object that implements the Iterable interface.

Also, if the right-hand side of the for(:) idiom is an array rather than an Iterable object, the internal code uses an int index counter and checks against array.length instead. See http://forums.sun.com/thread.jspa?messageID=2743233

上面敘述內容大意是說 Iterator可以用在任何有實作 Iterator interface 的資料結構,上面程式碼一定可以執行。但是這種寫法,如果你再使用 iteratorremove function,這種方式的 for loop(我們稱它為 for each loop)會不能用。

 

這次我用到 HashMap 資料結構,它沒實作 Iterator interface,所以會不能用,這次我的程式一直說有ConcurrentModificationException,但是沒有進一步的訊息,經學弟提醒說試著改用原本的 for loop,就發現問題了,我們自己原本的推斷是 Java 編譯器可能有對 for each loop 做處理,會開啓Multithread去執行for括號內的條件。

 

另外一個網頁的 Junky 提到 HashMap 沒實作 Iterator interface,並建議改用 Set 去取得 HashMap 在資料結構上屬於更上一層的 Map 資料,Map 就有做 http://www.java-forums.org/new-java/42778-each-loop-problem-using-hash-map.html

The for each loop only works with classes that implement the Iterable interface. I believe HashMap doesn’t. However you can get a Set from the Map which does implement Iterable.

 

Java本身的 Map 網頁 http://download.oracle.com/javase/6/docs/api/java/util/Map.html 就提到 Map 底下的一些資料結構有做 iterator,例如 treemap;而 HashMap 就沒實作。

網頁中的敘述

Some map implementations, like the TreeMap class, make specific guarantees as to their order; others, like the HashMap class, do not.