动态剔除ArrayList中的元素
这几天开发的时候遇到了动态删除ArrayList中的元素的场景,比较疑惑就做了几个小试验, 不对的地方请大家指出哈: 第一种:在java在的foreach循环中动态删除 代码:
public static void test1(){ List<Integer> testList = new ArrayList<Integer>(); testList.add(0); testList.add(1); testList.add(2); testList.add(3); testList.add(4); for(Integer i : testList){ System.out.println("when i="+i+" testList ="+testList); if(i==1){ testList.remove(i); } } }
结果: when i=0 testList =[0, 1, 2, 3, 4] Exception in thread "main" when i=1 testList =[0, 1, 2, 3, 4] java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) at java.util.AbstractList$Itr.next(AbstractList.java:343) at com.taobao.tripp.junit.dao.oldPlatform.MucheTest.test1(MucheTest.java:16) at com.taobao.tripp.junit.dao.oldPlatform.MucheTest.main(MucheTest.java:57) 结论:当动态从ArrayList删除元素之后,报不允许对象并发修改的错误。
第二种:通过得到List的长度来遍历List并动态删除。 代码: public static void test2(){ List<Integer> testList = new ArrayList<Integer>(); testList.add(0); testList.add(1); testList.add(2); testList.add(3); testList.add(4); for(int i=0;i<testList.size(); i++){ System.out.println("when i="+i +" testList ="+ testList+" testList.get(i)="+testList.get(i)); if(testList.get(i)==1){ testList.remove(0); } } } |
结果: when i=0 testList =[0, 1, 2, 3, 4] testList.get(i)=0 总结: 可以看到for循环中的i是一直自增一的,但是ArrayList的长度随着动态删除, 动态改变,所以用这种方法看起来是可以的,但是如果将代码中的remove(i) 改为remove(0)的话,当i=2的时候testList.get(i)还是会得到3, 也就是说因为0被删除了,2这个元素没有被遍历到。所以这种方式可以用来删 除当前节点以及此节点以后的节点,删除此节点以前的节点的话会造成部分元素 未被遍历到。
第三种:用Iterator遍历 代码:
public static void test3() { List<Integer> testList = new ArrayList<Integer>(); testList.add(0); testList.add(1); testList.add(2); testList.add(3); testList.add(4); Iterator<Integer> iterator = testList.iterator(); while(iterator.hasNext()) { Integer element = iterator.next(); System.out.println("when element ="+element+" testList="+testList); if(1==element) { iterator.remove(); } } }
when element =0 testList=[0, 1, 2, 3, 4] 总结:这种方法避免了删除当前节点前面节点的可能性,只能对当前节点进行操作,推荐使用, 网上很多帖子也比较推荐用这种方法,但是感觉不怎么灵活了就。 |