在使用for、foreach和iterator时,三者存在一些区别,当我们在遍历中对遍历对象进行修改时,会出现问题。
在开发中要避免在遍历中队遍历对象进行修改,如果需要,应该使用iterator安全地对对象进行删除操作
1. 三者对比
1.1.for
当我们使用for循环对list进行遍历时,如果途中删除了某个元素,那么会导致遍历次数减少
比如下面本应遍历1~5,但由于在2时,list.size减少了1,所以在遍历到4时便结束了,5没有被遍历到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Iterator;
public class MyTest { @Test public void test() { ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5);
int count = 0;
for (int i =0;i<list.size();i++){ count++; if(list.get(i)==2){ list.remove(i); } } System.out.println("循环次数:"+count);
} }
|
1.2.foreach
foreach底层实际是利用了iterator来完成的,所以当我们在遍历时修改了遍历的list,就会抛出ConcurrentModificationException异常。
这是因为在迭代器遍历执行next()方法时会验证modCount和expectedModCount是否相同
当我们调用list.remove()时,modeCount会+1,而expectedModCount不变,这就导致了报错。
所以当我们需要移除时,应该使用迭代器中的iterator.remove()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Iterator;
public class MyTest { @Test public void test() { ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); for(Integer i:list){ if(i==2){ list.remove(i); } } } }
|
1.3.iterator
使用iterator.remove()移除元素时modCount和expectedModCount都会+1,这样就可以保证两者相同。
但需要注意,在迭代过程中对元素进行修改会导致modCount+1,此时同样会抛出异常!
所以,如果需要修改元素,可以先删除,在迭代完成后再统一添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Iterator;
public class MyTest { @Test public void test() { ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5);
int count = 0; Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()){ count++; Integer next = iterator.next(); if(next==2){ iterator.remove(); } } System.out.println("循环次数:"+count); }
}
|
2.实际使用
下面是一段在开发过程中对一个jsonObject处理的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| JSONObject jsonObject = JSONObject.parseObject(genChart);
Iterator<String> iterator = jsonObject.keySet().iterator();
HashMap replaceMap = new HashMap();
while (iterator.hasNext()){ String key = iterator.next(); String newKey = key.trim(); if (!newKey.equals(key)) { replaceMap.put(newKey,jsonObject.get(key)); iterator.remove(); } }
jsonObject.putAll(replaceMap);
String newGenChart = JSON.toJSONString(jsonObject);
result.put("genChart",newGenChart);
|