以下函数以递归方式遍历列表并将其除以一半,并对子列表执行某些操作。如果列表大小为2,则递归会中断。我知道如果在迭代它时更改列表,则会发生并发修改异常。但我不使用迭代,它仍然会发生:
private static List<ParticipantSlot> divide(List<ParticipantSlot> list) {
int n = list.size();
//do something
if (n>2){
List<ParticipantSlot> l = divide(list.subList(0, n/2-1));
List<ParticipantSlot> r= divide(list.subList(n/2, n));
l.addAll(r);
return l;
}else{
return list;
}
}
答案 0 :(得分:7)
您正在使用addAll()
,它会迭代您在参数中提供的集合。现在subList
仅将视图返回到原始列表中,因此您尝试将值添加到原始列表的视图中,并迭代原始列表的不同部分。同时。邦。
如果您每次创建子列表的副本,它应该可以工作 - 尽管它效率很低。
答案 1 :(得分:3)
您会收到并发修改异常,因为子列表由原始列表支持:
返回的列表由此列表支持,因此返回列表中的非结构更改将反映在此列表中,反之亦然。返回的列表支持此列表支持的所有可选列表操作。
如果您想避免异常,请在修改之前复制第一个子列表。
答案 2 :(得分:1)
如果您使用的是ArrayList,可能需要将其更改为CopyOnWriteArrayList或ConcurrentLinkedQueue。
如果您使用的是多线程环境,则需要在数组周围添加synchronized
。
希望它有所帮助。