当我们在Java中对list集合内的元素进行增加、删除或修改操作的时候容易出现并发修改异常(ConcurrentModificationException),以下是个人总结的出现原因以及解决方法,如有错误,请及时指出。
出现原因:
在迭代器内遍历集合时,直接对集合元素进行操作。
使用foreach(增强for循环)遍历集合时,直接对集合元素进行操作。
注意:其实Java中的增强for循环底层是通过迭代器模式来实现的。
错误示例:
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//使用迭代器添加集合元素,ConcurrentModificationException
Iterator<String> li = list.iterator();
while (li.hasNext()) {
String s = li.next();
if (s.equals("world")) {
list.add("javascript");
}
}
//使用集合迭代器删除集合元素,ConcurrentModificationException
ListIterator<String> lit = list.listIterator();
while (lit.hasNext()) {
String s = lit.next();
if (s.equals("world")) {
list.remove("javascript");
}
}
//使用foreach遍历修改集合元素,ConcurrentModificationException
for (String s : list) {
if (s.equals("world")) {
list.remove("world");
list.add("javascript");
}
}
}
解决方法:
使用迭代器遍历集合来操作集合元素时,使用迭代器内提供的方法
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//创建集合迭代器
ListIterator<String> lit = list.listIterator();
//使用集合迭代器添加集合元素
while (lit.hasNext()) {
String s = lit.next();
if (s.equals("world")) {
lit.add("javascript");
}
}
//使用集合迭代器删除集合元素
while (lit.hasNext()) {
String s = lit.next();
if (s.equals("world")) {
lit.remove();
}
}
//使用集合迭代器修改集合元素
while (lit.hasNext()) {
String s = lit.next();
if (s.equals("world")) {
lit.remove();
lit.add("javascript");
}
}
}
使用普通for循环来对集合元素进行操作
思路一:正向操作 i++
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//普通for循环增加元素
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
if (s.equals("java")) {
list.add("javascript");
}
}
//普通for循环删除元素
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
if (s.equals("java")) {
list.remove(s);
i--;// 矫正位置
}
}
//普通for循环修改元素
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
if (s.equals("java")) {
list.remove(s);
list.add("javascript");
}
}
}
思路二:反向操作 i--
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//普通for循环增加元素
for (int i = list.size() - 1; i >= 0 ; i--) {
String s = list.get(i);
if (s.equals("java")) {
list.add("javascript");
}
}
//普通for循环删除元素
for (int i = list.size() - 1; i >= 0 ; i--) {
String s = list.get(i);
if (s.equals("java")) {
list.remove(s);
}
}
//普通for循环修改元素
for (int i = list.size() - 1; i >= 0 ; i--) {
String s = list.get(i);
if (s.equals("java")) {
list.remove(s);
list.add("javascript");
}
}
}