【发布时间】:2019-02-26 08:26:53
【问题描述】:
编辑 它的工作
group.getUsers().forEach(user -> {
user.removeGroup(group);
privilegeRepository.findAll().stream().
filter(privilege -> privilege.getName().startsWith(slugname.toUpperCase()))
.forEach(privilege -> {
user.removePrivilege(privilege);
privilegeRepository.delete(privilege);
});
});
我有嵌套的 for 循环,我想用 forEach 替换那个 for 循环:
for (User user : group.getUsers()) {
user.removeGroup(group);
for(Privilege privilege : user.getPrivileges()){
if (privilege.getName().startsWith(slugname.toUpperCase())){
user.removePrivilege(privilege);
privilegeRepository.delete(privilege);
}
}
}
到
group.getUsers().forEach(user -> {
user.removeGroup(group);
user.getPrivileges().stream().filter(privilege -> privilege.getName().startsWith(slugname.toUpperCase()))
.forEach(privilege -> {
user.removePrivilege(privilege);
privilegeRepository.delete(privilege);
});
});
它会抛出一个异常:
java.util.ConcurrentModificationException
【问题讨论】:
-
完整的堆栈跟踪会很有用,所以我们可以看到哪一行抛出了异常
-
user.getPrivileges()vsprivilegeRepository.findAll(): 看起来两者做的不一样 -
这里不使用流,使用老式迭代器可能更有意义,您可以调用
remove()来从用户权限中删除权限。 -
在迭代
user.getPrivileges时不能调用user.removePrivilege。您需要制作快照副本以进行迭代。 -
有趣的是为什么在第一个示例中没有得到
java.util.ConcurrentModificationException(使用嵌套的for循环)。我认为user.removePrivilege(privilege);仍然可以同时对您正在迭代的集合进行修改。