demo1
public class ConcurrentModificationExceptionTest {
@Test
public void testIterator() {
Set<String> books = new HashSet<String>();
books.add("a");
books.add("bb");
books.add("ccc");
Iterator<String> it = books.iterator();
while (it.hasNext()) {
String book = it.next();
if (book.length()==1) {
books.remove(book);
}
}
System.out.println(books);
}
@Test
public void testForEach() {
Set<String> books = new HashSet<String>();
books.add("a");
books.add("bb");
books.add("ccc");
for (String book : books) {
if (book.length()==1) {
books.remove(book);
}
}
System.out.println(books);
}
}
以上两个函数都抛出ConcurrentModificationException异常,原因是因为当使用Iterator迭代访问集合时,集合中的元素不能改变,只能通过iterator的remove方法删除上一次next方法返回的集合元素才可以否则将发生异常。iterator迭代器采用的是快速失败(fail-fast)机制,一旦在迭代过程中检测到该集合已经被修改(通常是程序中其他线程的修改),程序立即引发ConcurrentModificationException异常,而不是显示修改后的结果,这样可以避免共享资源而引发的潜在问题。同理使用foreach迭代访问集合元素时,该集合也不能被改变,否则将引发ConcurrentModificationException异常。注意iterator迭代变量和foreach循环变量都不是集合元素本身,系统只是依次把集合元素的值赋给迭代变量,因此在迭代或者循环中修改迭代变量的值是没有任何意义的。
demo2
public void testForEach() {
Set<String> books = new HashSet<String>();
books.add("a");
books.add("bb");
books.add("ccc");
int i = 0;
for (String book : books) {
book = "d"+i++;
}
System.out.println(books);
}