最近在写代码的时候遇到了遍历时删除List元素的问题,在此写一篇博客记录一下。

一般而言,遍历List元素有以下三种方式:

  • 使用普通for循环遍历
  • 使用增强型for循环遍历
  • 使用iterator遍历

使用普通for循环遍历

代码如下:

public class Main {public static void main(String[] args) throws Exception {List<Integer> list = new ArrayList<>();for (int i = 0; i < 5; i++)list.add(i);// list {0, 1, 2, 3, 4}for (int i = 0; i < list.size(); i++) {// index and numberSystem.out.print(i + " " + list.get(i));if (list.get(i) % 2 == 0) {list.remove(list.get(i));System.out.print(" delete");i--; // 索引改变!}System.out.println();}}
}

结果如下:

可以看到遍历删除偶数的结果是成功的,但是这种方法由于删除的时候会改变list的index索引和size大小,可能会在遍历时导致一些访问越界的问题,因此不是特别推荐。

使用增强型for循环遍历

public class Main {public static void main(String[] args) throws Exception {List<Integer> list = new ArrayList<>();for (int i = 0; i < 5; i++)list.add(i);// list {0, 1, 2, 3, 4}for (Integer num : list) {// index and numberSystem.out.print(num);if (num % 2 == 0) {list.remove(num);System.out.print(" delete");}System.out.println();}}
}

结果如下:

可以看到删除第一个元素时是没有问题的,但删除后继续执行遍历过程的话就会抛出ConcurrentModificationException的异常。

使用iterator遍历

public class Main {public static void main(String[] args) throws Exception {List<Integer> list = new ArrayList<>();for (int i = 0; i < 5; i++)list.add(i);// list {0, 1, 2, 3, 4}Iterator<Integer> it = list.iterator();while (it.hasNext()) {// index and numberint num = it.next();System.out.print(num);if (num % 2 == 0) {it.remove();System.out.print(" delete");}System.out.println();}}
}

结果如下:

可以看到顺利的执行了遍历并删除的操作,因此最推荐的做法是使用iterator执行遍历删除操作。

使用普通for循环遍历

public class Main {public static void main(String[] args) throws Exception {List<Integer> list = new CopyOnWriteArrayList<>();for (int i = 0; i < 5; i++)list.add(i);// list {0, 1, 2, 3, 4}for (int i = 0; i < list.size(); i++) {// index and numberSystem.out.print(i + " " + list.get(i));if (list.get(i) % 2 == 0) {list.remove(list.get(i));System.out.print(" delete");i--; // 索引改变!}System.out.println();}}
}

以上是关于非线程安全的ArrayList,如果是线程安全的CopyOnWriteArrayList呢?

使用普通for循环遍历

public class Main {public static void main(String[] args) throws Exception {List<Integer> list = new CopyOnWriteArrayList<>();for (int i = 0; i < 5; i++)list.add(i);// list {0, 1, 2, 3, 4}for (int i = 0; i < list.size(); i++) {// index and numberSystem.out.print(i + " " + list.get(i));if (list.get(i) % 2 == 0) {list.remove(list.get(i));System.out.print(" delete");i--; // 索引改变!}System.out.println();}}
}

结果如下:

可以看到遍历删除是成功的,但是这种方法由于删除的时候会改变list的index索引和size大小,可能会在遍历时导致一些访问越界的问题,因此不是特别推荐。

使用增强型for循环遍历

public class Main {public static void main(String[] args) throws Exception {List<Integer> list = new CopyOnWriteArrayList<>();for (int i = 0; i < 5; i++)list.add(i);// list {0, 1, 2, 3, 4}for (Integer num : list) {// index and numberSystem.out.print(num);if (num % 2 == 0) {list.remove(num);System.out.print(" delete");}System.out.println();}}
}

结果如下:

可以看见与ArrayList遍历删除时情况不同,CopyOnWriteArrayList是允许使用增强型for进行循环遍历删除的。

使用iterator遍历

public class Main {public static void main(String[] args) throws Exception {List<Integer> list = new CopyOnWriteArrayList<>();for (int i = 0; i < 5; i++)list.add(i);// list {0, 1, 2, 3, 4}Iterator<Integer> it = list.iterator();while (it.hasNext()) {// index and numberint num = it.next();System.out.print(num);if (num % 2 == 0) {it.remove();System.out.print(" delete");}System.out.println();}}
}

结果如下:


与ArrayList不同,由于CopyOnWriteArrayList的iterator是对其List的一个“快照”,因此是不可改变的,所以无法使用iterator遍历删除。

综上所述,当使用ArrayList时,我们可以使用iterator实现遍历删除;而当我们使用CopyOnWriteArrayList时,我们直接使用增强型for循环遍历删除即可,此时使用iterator遍历删除反而会出现问题。

正确在遍历中删除List元素相关推荐

  1. List遍历中删除元素

    List遍历主要有索引下标遍历.for循环遍历和Iterator迭代遍历,索引下标和for循环在遍历中删除元素都存在问题,Iterator迭代可以实现遍历中删除元素. 索引下标遍历 List<I ...

  2. JS遍历从数组中删除指定元素

    JS遍历从数组中删除指定元素,arr为目标数组,aim为目标对比项 当每次遍历全部内容需要删除的元素不超过一个时,以下两种方法都可用,虽然结果是正确的,但是还是不推荐使用,因为没有包含数组改变后角标值 ...

  3. java arraylist 对象 删除_如何从Java中的ArrayList对象中删除冗余元素?

    接口集不允许重复的元素.茶add() 此接口的方法接受元素并添加到Set对象,如果添加成功,则如果您尝试使用此方法添加现有元素,则返回true,添加操作将返回false. 因此,要删除ArrayLis ...

  4. php中删除数组元素的函数,php删除数组中的元素函数用法汇总

    php中删除数组元素是非常的简单的,主要是unset,array_splice,但是关于两者有,长时间混用,有的时候竟然分不出区别. 很多地方都这样区别unset,array_splice array ...

  5. java数组删除数组元素_如何在Java中删除数组元素

    java数组删除数组元素 When we create an array in Java, we specify its data type and size. This is used by JVM ...

  6. 在 PHP 中从数组中删除一个元素

    问: 有没有一种简单的方法可以使用 PHP 从数组中删除一个元素,从而使 foreach ($array) 不再包含该元素? 我认为将它设置为 null 会做到这一点,但显然它不起作用. 答1: hu ...

  7. java中Hashset集合删除元素_从Java中的HashSet中删除单个元素

    要从HashSet中删除单个元素,请使用remove()方法. 首先,创建一个HashSet-HashSet hs = new HashSet(); 现在,将元素添加到HashSet-hs.add(& ...

  8. python 可以根据元素值删除的是_python中删除某个元素的方法解析

    这篇文章主要介绍了python中删除某个元素的方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python中关于删除list中的某个元素,一 ...

  9. 从List集合中删除指定元素

    从List集合中删除指定元素的几种方式 最近在使用这个操作的时候搜索了一下网上的文章,发现有些能用有些不能用, 由于使用之前没有做详细的测试,导致程序bug,今天抽空做了一下总结和测试. packag ...

最新文章

  1. CTFshow 命令执行 web29
  2. STM32F103ZET6开发板PB3/4,PA13/14/15等I/O口的特殊配置
  3. Eigen求解数学问题(一)
  4. C++ 静态链表(用数组模拟动态链表)
  5. 重载session存储方式–session_set_save_handler()
  6. 并不能一蹴而就的s9t9
  7. PHP读取TXT中文乱码的解决方法
  8. 用Python做图像处理(PIL库的使用)
  9. postman 使用
  10. 系统内核快速编译并替换的方法
  11. 高并发的常见策略--大型web项目
  12. 【JY】2021全国首届工程仿真大赛154个项目视频教程分享
  13. Fabric官方教程(release 2.2)翻译及总结——使用CouchDB
  14. 提取ansible hosts分组IP
  15. 未来机器人生活的畅享之旅
  16. 【MySQL】JDBC编程
  17. 2010年美专利全球50强公司排名发布 IBM蝉联榜首
  18. C语言萌新写题第四天
  19. 16福师硬盘是计算机的,福师16春《计算机应用基础》在线作业一分析.docx
  20. 数据库中的变量和if语句的相关语法与案例

热门文章

  1. 信用评分模型建模流程
  2. js确认框confirm()用法实例详解
  3. 【教程】如何解决vs编译器scanf函数报错问题
  4. ETCD启动失败-connect: no route to host
  5. 二叉树非递归后序遍历
  6. JavaScript算法——快速排序
  7. mongodb gridfs java_MongoDB基于GridFS管理文件
  8. 【生成模型】Stable Diffusion原理+代码
  9. 技术人员应该如何追求个人价值【12年工作感想总结分享】
  10. defy手机突然搜索不到wifi信号的问题