对于集合的遍历操作,可以使用 itrator foreach for 循环,下面比较一下各自的优缺点
2016-06-28 16:00
846 查看
List<String> list = new ArrayList<String>(); list.add("11"); list.add("11"); list.add("33"); list.add("44"); for (int i =0; i < list.size(); i++) { if(list.get(i).equals("11")){ list.remove(i); } } 输出:[11,33, 44]
分析:list底层实现是一个数组,删除一个之后下标发生了左移,发生错误,无论是修改还是删除,不建议使用这种方式
Iterator<String> it = list.iterator(); while(it.hasNext()){ String temp = (String)it.next(); if(temp.equals("11")){ it.remove(); } } System.out.println(list.toString()); 输出:[33, 44]
分析:为什么这个可以呢?因为itrator的remove()方法有一步:expectedModCount = modCount,删除很方便,但是不能做修改
for(String loop : list){ if(loop.equals("11")){ list.remove(loop); } if(loop.equals("22")){ list.remove(loop); } } System.out.println(list.toString()); 输出: java.util.ConcurrentModificationException
分析:list底层有一个modcount标记,每次进行修改前会加1,再次删除是使用 if (modCount != expectedModCount) 进行判断是否相等,相等才可以操作。不能进行删除,但是可以修改
再补充一个问题:
String[] vendorIdArr = {"11","22","33"}; List<String> vendorIdResultList = Arrays.asList(vendorIdArr); vendorIdResultList.remove(0); 输出:java.lang.UnsupportedOperationException
分析:java.util.Arrays$ArrayList 没有重写add(), removew()方法 ,使用 List vendorIdResultList = new ArrayList(Arrays.asList(vendorIdArr))代替List vendorIdResultList = Arrays.asList(vendorIdArr)即可
总结:修改使用foreach(),删除使用iterator(),既要删除又要修改只能采做标记的方式,遍历后再根据标记操作,如果非得使用一个方式进行,不是没有,那就是使用for循环,但是是从尾部向头部遍历,这样就可以避免元素删除后未遍历的元素下标发生偏移,但是不建议使用。
当工作逐渐占据了生活的全部,只能从代码中窃取快乐。
相关文章推荐
- 文件遍历排序函数
- Lua 学习笔记之C API 遍历 Table实现代码
- C#遍历文件夹后上传文件夹中所有文件错误案例分析
- C#中遍历Hashtable的4种方法
- Erlang中遍历取出某个位置的最大值代码
- C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析
- C++实现图的邻接表存储和广度优先遍历实例分析
- 举例讲解C语言程序中对二叉树数据结构的各种遍历方式
- C++非递归队列实现二叉树的广度优先遍历
- php遍历目录方法小结
- 一个目录遍历函数
- php遍历删除整个目录及文件的方法
- PHP遍历文件夹与文件类及处理类用法实例
- PHP遍历XML文档所有节点的方法
- php中使用key,value,current,next和prev函数遍历数组的方法
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- C#使用foreach遍历哈希表(hashtable)的方法
- php递归遍历多维数组的方法
- C#使用yield关键字让自定义集合实现foreach遍历的方法
- C#常见的几种集合 ArrayList,Hashtable,List<T>,Dictionary<K,V> 遍历方法对比