Java初学者操作ArrayList添加元素时遇ConcurrentModificationException异常
解决Java中
ConcurrentModificationException异常的问题 嘿,这个问题我刚学Java的时候也踩过坑!你遇到的ConcurrentModificationException,说白了就是你在遍历一个集合的同时,直接修改了这个集合的结构——比如用forEach或者for-each循环遍历的时候,调用了集合的add()、remove()这类改变集合大小的方法,集合的「快速失败」机制就会抛出这个异常来提醒你。
从你贴的代码片段来看,你在遍历tmpList的时候操作了anList——如果anList是你正在遍历的集合(比如在forEach的逻辑里你又去遍历了anList并修改它),那肯定会触发这个异常。举个典型的场景:要是你在else分支里用for-each循环遍历anList,同时又往anList里添加新的列表分组,这就会直接触发异常。
给你几个可行的解决思路:
1. 用基于索引的普通for循环代替for-each/forEach
这种方式不会触发集合的迭代器检查,你可以安全地在遍历过程中修改集合:
tmpList.forEach(word -> { if(anList.isEmpty()) { ArrayList<String> tmp = new ArrayList<>(); tmp.add(word); anList.add(tmp); } else { boolean added = false; // 用索引循环遍历anList,避免迭代器的并发修改检查 for(int i = 0; i < anList.size(); i++) { List<String> group = anList.get(i); if(isAnagram(group.get(0), word)) { // 假设你有判断变位词的方法 group.add(word); added = true; break; } } if(!added) { anList.add(new ArrayList<>(List.of(word))); } } });
2. 使用ListIterator来遍历和修改集合
ListIterator提供了安全的add()方法,不会触发并发修改异常,因为它是迭代器自身支持的修改操作:
tmpList.forEach(word -> { if(anList.isEmpty()) { ArrayList<String> tmp = new ArrayList<>(); tmp.add(word); anList.add(tmp); } else { boolean added = false; ListIterator<List<String>> iterator = anList.listIterator(); while(iterator.hasNext()) { List<String> group = iterator.next(); if(isAnagram(group.get(0), word)) { group.add(word); added = true; break; } } if(!added) { // 用迭代器的add方法添加新元素,不会触发异常 iterator.add(new ArrayList<>(List.of(word))); } } });
3. 先收集需要添加的元素,遍历完再统一处理
如果你不想改遍历方式,可以先把要添加的新分组存起来,等遍历完anList之后再加入集合,这样就不会在迭代过程中修改集合结构:
tmpList.forEach(word -> { boolean added = false; // 先遍历anList完成匹配操作,不修改集合结构 for(List<String> group : anList) { if(isAnagram(group.get(0), word)) { group.add(word); added = true; break; } } // 遍历完成后再添加新分组,不会触发异常 if(!added) { anList.add(new ArrayList<>(List.of(word))); } });
另外补充一句:如果你是在遍历tmpList的时候修改tmpList本身(比如在forEach里调用tmpList.add()),那也会抛出同样的异常,这时候用上面的方法也能解决。
内容的提问来源于stack exchange,提问作者Tomek Szymański
相关产品推荐
相关产品推荐

