如题所示:Java foreach 中List移除元素抛出ConcurrentModificationException
看demo:
public static void main(String[] args) {
SimplifyVehicleSo s = new SimplifyVehicleSo();
List<VehicleAttribute> attributes = new ArrayList<>();
VehicleAttribute attribute = new VehicleAttribute();
attribute.setAttributeEnName("df");
attribute.setAttributeValueList(Arrays.asList("sfs","fs"));
VehicleAttribute attributeq = new VehicleAttribute();
attributeq.setAttributeEnName("df");
attributeq.setAttributeValueList(Collections.emptyList());
attributes.add(attribute);
attributes.add(attributeq);
s.setVehicleAttributeList(attributes);
System.out.println(JSON.toJSONString(s));
for (VehicleAttribute vehicleAttribute : s.getVehicleAttributeList()) {
if (vehicleAttribute == null) {
continue;
}
//过滤值为空的属性
if (StringUtils.isNotBlank(vehicleAttribute.getAttributeEnName()) && CollectionUtils.isEmpty(vehicleAttribute.getAttributeValueList())) {
s.getVehicleAttributeList().remove(vehicleAttribute);
}
}
System.out.println(JSON.toJSONString(s));
}
结果:
看错误提示信息:
ConcurrentmodificationException;
是因为在迭代的时候,移除了一个元素,二迭代器还不知道,数量已经变了,在next取值的时候就会报错。
因此,我们不能这样迭代移除,可以使用iteator,iteator会跟新计数器里面的值,因此不会导致异常:
demo:
Iterator<VehicleAttribute> iterator = so.getVehicleAttributeList().iterator();
while (iterator.hasNext()) {
VehicleAttribute vehicleAttribute = iterator.next();
if (vehicleAttribute == null) {
continue;
}
//过滤值为空的属性
if (StringUtils.isNotBlank(vehicleAttribute.getAttributeEnName()) && CollectionUtils.isEmpty(vehicleAttribute.getAttributeValueList())) {
iterator.remove();
}
}
当然啦,可以使用一个新的list对象接受他。这样就避免移除的问题,
List<VehicleAttribute> ll = new ArrayLsit<>();
Iterator<VehicleAttribute> iterator = so.getVehicleAttributeList().iterator();
while (iterator.hasNext()) {
VehicleAttribute vehicleAttribute = iterator.next();
if (vehicleAttribute == null) {
continue;
}
//过滤值为空的属性
if (StringUtils.isNotBlank(vehicleAttribute.getAttributeEnName()) && CollectionUtils.isEmpty(vehicleAttribute.getAttributeValueList())) {
continue;
}
ll.add(vehicleAttribute);
}
最后,可以使用Lamda表达式轻松过滤值为空的选项
so.getVehicleAttributeList().stream.filter(attr -> CollectionUtils.isNotEmpty(attr.getAttributeValueList())).collect(Collectors.toList())