集合之List--List如何安全删除

打印 上一主题 下一主题

主题 999|帖子 999|积分 2997

在java中,List的删除操纵大概会导致ConcurrentModificationException一场,尤其是在遍历时直接调用removce(方法)
一、使用Iterator删除

Iterator提供了安全的删除方法remove(),可以在遍历时删除元素
  1. List<String> list = new ArrayList<>();
  2. list.add("A");
  3. list.add("B");
  4. list.add("C");
  5. Iterator<String> iterator = list.iterator();
  6. while (iterator.hasNext()) {
  7.    String item = iterator.next();
  8.    if (item.equals("B")) {
  9.        iterator.remove(); // 安全删除
  10.    }
  11. }
  12. System.out.println(list); // 输出: [A, C]
复制代码
优点:


  • 安全且高效
  • 适用于单线程环境
二、使用removeIf(方法)(java8+)

java8引入了removeIf方法,可以根据条件删除元素
  1. List<String> list = new ArrayList<>();
  2. list.add("A");
  3. list.add("B");
  4. list.add("C");
  5. list.removeIf(item -> item.equals("B")); // 删除满足条件的元素
  6. System.out.println(list); // 输出: [A, C]
复制代码
优点


  • 代码简洁,得当函数式编程风格。
  • 内部使用 Iterator,安全高效。
三、使用for循环倒序遍历

如果使用普通的for循环删除元素,建议倒序遍历,避免索引错误问题
  1. List<String> list = new ArrayList<>();
  2. list.add("A");
  3. list.add("B");
  4. list.add("C");
  5. for (int i = list.size() - 1; i >= 0; i--) {
  6.    if (list.get(i).equals("B")) {
  7.        list.remove(i); // 删除元素
  8.    }
  9. }
  10. System.out.println(list); // 输出: [A, C]
复制代码
优点


  • 避免索引错位问题。
  • 适用于需要根据索引删除的场景。
四、使用CopyOnWriteArrayList

如果需要在多线程环境下安全删除元素,可以使用CopyOnWriteArrayList,它在修改时创建底层数据的新副本,得当多读写啊后的场景
  1. List<String> list = new CopyOnWriteArrayList<>();
  2. list.add("A");
  3. list.add("B");
  4. list.add("C");
  5. for (String item : list) {
  6.    if (item.equals("B")) {
  7.        list.remove(item); // 安全删除
  8.    }
  9. }
  10. System.out.println(list); // 输出: [A, C]
复制代码
注意


  • CopyOnWriteArrayList 的写操纵性能较差,由于每次修改都会创建新副本。
  • 得当多线程环境。
五、使用Collections.synchronizedList加锁

如果使用Collecions.synchronizedList包装List,需要手动加锁以保证线程安全
  1. List<String> list = Collections.synchronizedList(new ArrayList<>());
  2. list.add("A");
  3. list.add("B");
  4. list.add("C");
  5. synchronized (list) {
  6.    Iterator<String> iterator = list.iterator();
  7.    while (iterator.hasNext()) {
  8.        String item = iterator.next();
  9.        if (item.equals("B")) {
  10.            iterator.remove(); // 安全删除
  11.        }
  12.    }
  13. }
  14. System.out.println(list); // 输出: [A, C]
复制代码
优点


  • 线程安全。
  • 适用于多线程环境
六、使用Stream过滤

如果需要删除满意条件的元素并生成新表,可以使用Stream的filter方法
  1. List<String> list = new ArrayList<>();
  2. list.add("A");
  3. list.add("B");
  4. list.add("C");
  5. List<String> result = list.stream()
  6.                          .filter(item -> !item.equals("B")) // 过滤掉 "B"
  7.                          .collect(Collectors.toList());
  8. System.out.println(result); // 输出: [A, C]
复制代码
优点


  • 不修改原列表,生成新列表。
  • 得当函数式编程风格。
总结

方法适用场景特点Iterator.remove()单线程环境安全高效removeIf()Java 8+,单线程环境简洁,得当函数式编程倒序遍历 for 循环根据索引删除避免索引错位CopyOnWriteArrayList多线程环境线程安全,得当读多写少Collections.synchronizedList + 锁多线程环境线程安全,需要手动加锁Stream.filter()生成新列表不修改原列表,得当函数式编程
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

钜形不锈钢水箱

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表