【问题标题】:how to prevent Concurrent Modification Exception while inserting to lists插入列表时如何防止并发修改异常
【发布时间】:2021-05-25 20:45:43
【问题描述】:

我必须通过 categoriesproviders 方法插入不同类型的列表,我向它们插入 Provider 和 Category 类型。每次我想将类别或提供者添加到我的产品时,这些方法都会调用并接收来自我的服务类的输入。如果我评论categoriesproviders 之一,我会测试它会很好,但他们都在课堂上我有Concurrent Modification Exception 我想知道如何解决它?

    private List<Category> categories;
private List<Provider> providers;

    public void addProvider (Provider p){
        if(providers==null){
            providers=new ArrayList<>();
        }
        providers.add(p);
    }

    public void addCategory (Category cat){
        if(categories==null){
            categories=new ArrayList<>();
        }
        categories.add(cat);

    }

这是我的服务方法,我将其添加到此处,以便您更清楚地了解调用categoriesproviders 方法。产品对象有一个类别列表和提供者列表。如您所见,我正在使用 jpa 和 springboot 进行开发

   public void saveProduct(Product product){
        Product postProduct=new Product();
        postProduct.setCategories(product.getCategories());
        postProduct.setName(product.getName());
  
       List<Provider> tempo= product.getProviders();
        Provider providerInstans=new Provider();
        for(Provider p: tempo){

            providerInstans.setName(p.getName());
            providerInstans.setId(p.getId());
               Provider po=providerRepository.findByName(providerInstans.getName());
             postProduct.addProvider(po);

        }
        
        List<Category> temp=product.getCategories();
        Category categoryInstance=new Category();
        for(Category i:temp) {
            categoryInstance.setName(i.getName());

            categoryInstance.setId(i.getId());
            // Category a=categoryRepository.findByName("phone");
            String name = categoryInstance.getName();
            System.out.println(name);
            System.out.println("value" + categoryRepository.findById(1));
            Category a = categoryRepository.findById(1);
           postProduct.addCategory(a);

        }
        productRepository.save(postProduct);
    }

【问题讨论】:

  • 在遍历列表时不要修改它(在你的 for-each 循环中)。 (注意,最好将字段初始化为new ArrayList&lt;&gt;(),而不是让它们为空并检查add 方法;调用getProducts 以返回空而不是空的代码更友好。)跨度>
  • 我不明白我需要更改哪一部分。可以请您发布需要更改的部分吗?
  • 使用显式的Iterator 迭代列表,并通过迭代器进行添加。

标签: java spring jpa


【解决方案1】:

我猜,你通过调用分配给postProduct已经创建的列表

postProduct.setCategories(product.getCategories());

然后是你的代码:

List<Category> temp=product.getCategories();
Category categoryInstance=new Category();
for(Category i:temp) {
    postProduct.addCategory(a);
}

这里的 for 循环 temp 列表与之前分配给 postProduct 的列表相同,因此您在迭代时修改相同的类别列表。它的错误。不允许在列表中添加项目,同时在循环中对其进行迭代。

【讨论】:

  • 你可以这样做,但只能通过迭代器。
  • 在这种情况下是个坏主意。用户认为他有两个列表,但对同一个列表有两个引用。通过使用迭代器,用户可以破坏使用列表的程序的另一部分。
  • 这可能是一个坏主意,也可能不是一个坏主意,这取决于您在应用程序中一无所知的事情,但您当然可以这样做,这与您的答案中声称的相反。
  • 你是对的。迭代器是在通过迭代器迭代时更改集合的理想选择。我只是向新用户指出他的错误。我认为他没有发现在 Product 实例中意外使用了一个引用。
猜你喜欢
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2016-11-19
  • 1970-01-01
  • 2017-06-13
  • 2012-03-21
相关资源
最近更新 更多