带有迭代器的ConcurrentModificationException

时间:2018-07-12 22:12:36

标签: java spring-data-jpa

我在DTO中拥有

public class ProductTypesDto extends BaseDto {
  private List<Integer> colors = new ArrayList<>();
  ...
}

在我的豆子里

@Entity
public class ProductTypes 
   @ManyToMany
   private Set<Colors> colors = new HashSet<>();
   ...
}

用户可以为productTypes添加和删除颜色

在DTO到Bean的转换中,我这样做

private void convertToBeans(ProductTypesDto dto, ProductTypes beans) {
    //add element
    for (Integer color : dto.getColors()) {
        if (beans.getColors().stream().noneMatch(e -> Objects.equals(e.getId(), color))) {
            Optional<Colors> optColors = colorsRepository.findById(color);
            if (optColors.isPresent()) {
                beans.addColor(optColors.get());
            }
        }
    }
    //remove element
    for (Iterator<Colors> iterator = beans.getColors().iterator(); iterator.hasNext();) {
        Colors color = iterator.next();

        if (dto.getColors().stream().noneMatch(e -> e.intValue() == color.getId())) {

            Optional<Colors> optColors = colorsRepository.findById(color.getId());
            if (optColors.isPresent()) {
                beans.removeColor(optColors.get());
            }

        }
    }
}

代码运行时,我得到

  

java.util.ConcurrentModificationException:空

似乎可以在 iterator.next();

上获得此功能

2 个答案:

答案 0 :(得分:5)

您无法通过调用最可能执行beans.getColors()的{​​{1}}来遍历beans.removeColor()集合并从中删除。

要从基础集合中删除当前遍历的元素,请使用Iterator.remove()方法,例如替换:

colors.remove()

具有:

beans.removeColor(optColors.get());

答案 1 :(得分:2)

尝试做

iterator.remove()

代替

beans.removeColor(optColors.get());

请参见documentation for remove()。注意评论

  

“如果在迭代进行过程中以其他方式(而不是通过调用此方法)修改基础集合,则未指定迭代器的行为。”