目录
上面是基于ArrayList探讨的并发修改异常,下面介绍不会抛出并发修改异常的集合
总结:
【对于ArrayList/LinkedList等非线程安全集合遍历中的添加移除元素的操作:
- for增强循环的foreach;[continue,break起作用]-[循环中不可移除元素-并发修改异常]
- Iterator迭代器;[continue,break起作用]-[循环中可以iterator.remove()移除元素-循环中不可以list.remove(x)移除元素(也不可以list.add(x)添加元素)否则并发修改异常]-[多线程时需要对Iterator对象加锁synchronized (it){...}]
- lambda流的foreach;[continue,break填入报错,return 效果同 continue]-[循环中不可移除元素-空指针异常]
- 如果需要在遍历过程中同时删除和添加元素,可以使用ListIterator。
】
测试:
/**
* 总结:【
* for增强循环的foreach;[continue,break起作用]-[循环中不可移除元素-并发修改异常]
* Iterator迭代器;[continue,break起作用]-[循环中可以iterator.remove()移除元素-循环中不可list.remove(x)移除元素否则并发修改异常]-[多线程时需要对Iterator对象加锁synchronized (it){...}]
* lambda流的foreach;[continue,break填入报错,return 效果同 continue]-[循环中不可移除元素-空指针异常]
* 】
* @param args
*/
public static void main(String[] args) {
List<Integer> list = new ArrayList();
list.add(1);list.add(1);
list.add(1);list.add(2);
list.add(1);list.add(1);
//for增强循环
for (Integer i : list) {
if(i.compareTo(2) == 0){
continue;/*起作用*/
//break;
//return;
}
System.out.println(i);
}
for (Integer i : list) {//【抛出java.util.ConcurrentModificationException】
if(i.compareTo(2) == 0){
System.out.println("1size="+list.size());//6
list.remove(i);
System.out.println("2size="+list.size());//5
}
}
//迭代器<->for增强循环
Iterator it = list.iterator();
while (it.hasNext()){
int p = (int)it.next();
if(p == 2){
continue;/*起作用*/
//break;
//return;
}
System.out.println(p);
}
synchronized (it) {//==如果并发操作,需要对 Iterator 对象加锁==
while (it.hasNext()){
int p = (int)it.next();
if(p == 2){
System.out.println("1size="+list.size());//6
//list.remove(p);//【抛出java.util.ConcurrentModificationException】
it.remove();//[[不报错且达到效果]].
// 在阿里巴巴Java开发手册中原话:不要在 foreach 循环里进行元素的 remove/add 操作。
// remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。
System.out.println("2size="+list.size());//5
}
}
}
//lambda流循环
list.stream().forEach(e -> {
if(e.intValue() == 2){
//continue;//报错:continue outside of loop
//break;//报错: break outside switch or loop
return;//效果同loop中的continue;
}
System.out.println(e);
});
list.stream().forEach(e -> {//【抛出java.lang.NullPointerException】
if(e.intValue() == 2){
System.out.println("11size="+list.size());//6
list.remove(e);
System.out.println(e);//2
System.out.println("22size="+list.size());//5
}
});
}
补充:
ListIterator
Iterator的设计中只提供了移除元素的方法,并没有提供遍历时添加元素的直接方法。
ListIterator的设计中提供了在遍历过程中添加和移除元素的直接方法。
ListIterator:如果需要在遍历过程中同时删除和添加元素,可以使用ListIterator,并结合使用它的remove()和add()方法。