关于List遍历过程中删除元素报错问题

报错:

1
2
3
java.util.ConcurrentModificationException: null
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909) ~[na:1.8.0_231]
at java.util.ArrayList$Itr.next(ArrayList.java:859) ~[na:1.8.0_231]

问题代码:

1
2
3
4
5
for (RptShiftCashCurrencyNEntity rptShiftCashCurrencyNEntity : rptShiftCashCurrencyNEntityList) {
if ("B".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "G".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "N".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "8".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "9".equals(rptShiftCashCurrencyNEntity.getPosPayType())) {
rptShiftCashCurrencyNEntityList.remove(rptShiftCashCurrencyNEntity);
}
}

在解决问题前,先看一段简化代码:

1
2
3
4
5
for(String s:list){
if(s.equals("B")){
list.remove(x);
}
}

这种写法会存在问题,会抛出ConcurrentModificationException。 因为元素在使用的时候发生了并发的修改,导致异常抛出。但是删除完毕马上使用break跳出,则不会触发报错。

解决:

使用迭代器完成删除。

1
2
3
4
5
6
7
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
if(s.equals("B")){
it.remove();
}
}

问题代码修改为:

1
2
3
4
5
6
7
Iterator<RptShiftCashCurrencyNEntity> it = rptShiftCashCurrencyNEntityList.iterator();
while(it.hasNext()) {
RptShiftCashCurrencyNEntity rptShiftCashCurrencyNEntity = it.next();
if ("B".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "G".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "N".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "8".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "9".equals(rptShiftCashCurrencyNEntity.getPosPayType())) {
it.remove();
}
}

也可以使用java8特性removeIf方法:

1
rptShiftCashCurrencyNEntityList.removeIf(rptShiftCashCurrencyNEntity -> "B".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "G".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "N".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "8".equals(rptShiftCashCurrencyNEntity.getPosPayType()) || "9".equals(rptShiftCashCurrencyNEntity.getPosPayType()));