文章

集合遍历的时候删除元素的方法

集合遍历的时候删除元素的方法

在看阿里巴巴java开发手册时,有一条建议是这样的。

【强制】不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。

反例:

1
ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);for (Integer item : list) {    if (item == 3)        list.remove(item);}

说明:这个例子的执行结果会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结果吗?

此时程序会抛出并发修改异常: java.util.ConcurrentModificationException

我们将ArrayList 换成 LinkedList 后,结果也是一样的

使用对ArrayList索引遍历,并删除每个元素

1
ArrayList<String> list = new ArrayList<>();list.add("111");list.add("222");list.add("333");System.out.println("befor: "+list.size());for (int i = 0; i < list.size(); i++) {    list.remove(i);}for (String item : list) {    System.out.println(item);}System.out.println("after: "+list.size());

结果如下:

1
befor: 3222after: 1

此时我们再尝试使用map做同样的操作,可以看到map的几种遍历方法都不能正确的删除

1
Map<Integer,Integer> map = new HashMap<>();map.put(1,1);map.put(2,2);map.put(3,3);for (Integer integer : map.keySet()) {    map.remove(integer);}for (Map.Entry<Integer, Integer> item : map.entrySet()) {    map.remove(item.getKey());}

正例:

1
Iterator<String> it= a.iterator();while(it.hasNext()){    String temp = it.next();    if(删除元素的条件){        it.remove();    }}

同样地,对于HashMap, 也采用迭代器的方法

1
Map<Integer,Integer> map = new HashMap<>();map.put(1,1);map.put(2,2);map.put(3,3);Iterator<Map.Entry<Integer, Integer>> iterator = map.entrySet().iterator();while (iterator.hasNext()){    if (iterator.next().getKey() == 2){        iterator.remove();    }}map.forEach((k,v)->{    System.out.println("key: "+k+"  value: "+v);});

可以得到如下结果:

1
key: 1  value: 1key: 3  value: 3
本文由作者按照 CC BY 4.0 进行授权