在Java 8的流式API或者增强的for循环(for-each)中,如果我需要在遍历List的同时向该列表添加或删除元素,应该怎样设计代码以避免并行修改导致的并发问题?
时间: 2024-12-08 19:22:29 浏览: 12
在Java 8的流式API或增强的`for-each`循环中,由于并发修改List可能会引发`ConcurrentModificationException`异常,当你需要在迭代过程中更新列表时,应该采取一些策略来避免这种问题。一种常见的做法是使用`CopyOnWriteArrayList`,这是线程安全的,它在内部维护了一个读取视图和一个写入视图,只有在写操作(如添加或删除元素)时才会复制当前列表。
如果你使用普通的List,可以考虑以下几种方式:
1. 使用`Iterator`:创建一个新的`Iterator`来遍历原始列表,然后在`hasNext()`和`next()`之间对列表进行修改。这种方法不会抛出异常,因为`Iterator`是线程不安全的,所以在多线程环境下需要注意同步。
```java
List<String> list = ...;
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
// 在这里修改item或list
}
```
2. 切换到新的集合:遍历时创建一个新列表,将修改后的元素添加进去。
```java
List<String> originalList = ...;
List<String> newList = new ArrayList<>(originalList);
newList.addAll(originalList.stream()...); // 这里是对原列表做操作
originalList = newList; // 更新原列表
```
3. 使用`forEachOrdered`:如果只需要按照插入顺序修改,并且不允许并发修改,你可以使用`forEachOrdered`,它会保证元素的遍历顺序。
```java
list.forEachOrdered(item -> {
// 对item进行处理,可能修改list,但不推荐在forEachOrdered内部直接修改list
});
```
阅读全文