遍历的同时修改一个List有几种方式?
1 个回答
为了击碎你伪装的表面,我只能用尽全身力气挥出那惊鸿的半月弧光。云说在遍历 `List` 的同时修改元素时,需要避免 `fail-fast` 机制引发的异常。以下是几种有效的处理方式: ### 1. 使用普通 `for` 循环(不推荐,可能导致漏删) - 在遍历时可以通过索引进行修改,但删除元素后需要手动调整索引,容易出错。 ```java for (int i = 0; i < list.size(); i++) { if (condition) { list.remove(i); i--; // 避免漏删 } } ``` ### 2. 使用倒序 `for` 循环(可以用) - 通过倒序遍历可以避免索引调整的问题,删除后不会影响未处理的元素。 ```java for (int i = list.size() - 1; i >= 0; i--) { if (condition) { list.remove(i); } } ``` ### 3. 使用 `Iterator` 的 `remove` 方法(推荐) - 使用迭代器进行遍历,并通过 `Iterator` 的 `remove()` 方法删除元素,可以安全地修改集合。 ```java Iterator<Element> iterator = list.iterator(); while (iterator.hasNext()) { Element element = iterator.next(); if (condition) { iterator.remove(); } } ``` ### 4. 使用副本(可以用) - 创建一个 `List` 的副本进行遍历,在副本上操作不会影响原列表的遍历。 ```java List<Element> listCopy = new ArrayList<>(list); for (Element element : listCopy) { if (condition) { list.remove(element); } } ``` ### 5. 使用线程安全的 `CopyOnWriteArrayList`(适用于并发环境) - `CopyOnWriteArrayList` 支持遍历时修改,但在多线程情况下效率可能较低,适用于并发环境。 ```java List<Element> list = new CopyOnWriteArrayList<>(originalList); for (Element element : list) { if (condition) { list.remove(element); } } ``` ### 6. 使用 `Stream` 的 `filter` 方法(推荐) - `Stream` 的 `filter` 方法不会影响原集合,而是生成一个新的集合,便于过滤操作。 ```java List<Element> filteredList = list.stream() .filter(element -> !condition) .collect(Collectors.toList()); ``` ### 7. 使用 `removeIf` 方法(推荐) - 从 Java 8 开始,`List` 提供了 `removeIf` 方法,可以直接删除符合条件的元素,简洁高效。 ```java list.removeIf(element -> condition); ``` ### 总结 - **优先使用 `Iterator` 的 `remove()` 方法、`removeIf()` 方法**,因为它们既简洁又避免了 `fail-fast` 异常。 - **Stream 和副本方法** 适合需要生成新集合的场景。发布于 2024-11-09 11:39 •IP属地 天津举报评论收藏
公众号进入网站体验更佳

