我遇到了一个问题,这个集合上的迭代器。这是一个小项目,我用spring初始化程序创建的。
我使用Tomcat的Sping Boot 。之前我使用了for循环,然后我在这里看到了这个答案Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop,并试图将第一个答案适应我的情况。
唯一的问题是,我必须在删除之前从双向一对多、多对一关系中分离两个实体Parent和Child。即使我使用迭代器,我仍然会得到这个错误。
@PostMapping("/savecart")
public ResponseEntity<String> saveCartToDb(@RequestBody Set<CartProduct> cartProductList, Principal principal) {
User logedInUser = userService.findUserByUsername(principal.getName()).get();
Set<CartProduct> cartItemList = logedInUser.getCartProduct();
for (CartProduct cartProduct : cartProductList) {
cartProduct.setUser(logedInUser);
}
userService.saveNewUser(logedInUser);
log.info("In saveCartToDb()");
if (cartItemList.isEmpty()) {
logedInUser.setCartProduct(cartProductList);
userService.saveNewUser(logedInUser);
} else {
for (Iterator<CartProduct> iterator = cartItemList.iterator(); iterator.hasNext();) {
CartProduct cartItem = iterator.next();
if (cartItem != null) {
// Remove the current element from the iterator and the list.
cartItem.dismissParent();
logedInUser.dismissChild(cartItem);
iterator.remove();
userService.saveNewUser(logedInUser);
}
}
// for(CartProduct cartItem : cartItemList){
// cartItem.dismissParent();
// logedInUser.dismissChild(cartItem);
// userService.saveNewUser(logedInUser);
// }
cartProductService.deleteAllProductIds();
for (CartProduct cartProduct : cartProductList) {
cartProduct.setUser(logedInUser);
}
logedInUser.setCartProduct(cartProductList);
userService.saveNewUser(logedInUser);
}
return ResponseEntity.ok().body(cartProductList.toString());
}
我用来解耦的方法
第一个
有没有一种方法可以修改迭代器,不再收到这个错误?或者有没有一个更好的解决方案,与迭代器?
1条答案
按热度按时间2vuwiymt1#
根据你的异常
因此,您使用了
HashMap
,并且收到了ConcurrentModificationException
。但是,等等,你的代码中没有任何
HashMap
,对吗?您有
cartItemList.iterator()
,而cartItemList
宣告为Set<CartProduct>
。您所提供的实作也会是HashSet
。但是**
HashSet
是使用HashMap
从java
在后台实现的。因此,您遇到的错误提到了HashMap
。从documentation开始
公共类并发修改异常**扩展运行时异常
当不允许对对象进行并发修改时,检测到此类修改的方法可能会引发此异常。例如,通常不允许一个线程修改Collection,而另一个线程正在对其进行迭代。通常,在这些情况下,迭代的结果是未定义的。一些迭代器实现(包括JRE提供的所有通用集合实现)可以选择抛出此异常。执行此操作的迭代器被称为故障快速迭代器,因为它们快速而干净地失败,而不是冒着在未来的不确定时间的任意的、非确定性的行为的风险。
请注意,这个例外状况并不一定表示对象已由不同的执行绪同时修改。如果单一执行绪发出一系列违反对象契约的方法叫用,对象可能会掷回这个例外状况。例如,如果执行绪在使用故障快速迭代器(Fail-fast Iterator)反覆运算集合时,直接修改集合,迭代器将抛出此异常。
HashMap
和HashSet
提供了一个故障快速迭代器,这意味着在迭代过程中不允许修改集合。为了解决您的问题,您应该避免在迭代期间修改集合。
所以下面的代码块
可以重写为
因此,您只需在迭代过程中收集所有需要删除的元素,并仅在迭代后调用删除操作。