Java 传递arraylist的副本以避免并发修改异常

Java 传递arraylist的副本以避免并发修改异常,java,concurrentmodification,Java,Concurrentmodification,下面是抛出ConcurrentModificationException的java代码 下面是正在声明的列表 List<BrokerInvoiceLineItem> brokerInvoiceLineItems= new ArrayList<BrokerInvoiceLineItem>(); brokerInvoiceLineItems=brokerInvoice.getLineItems(); 现在的问题是,如果brokerInvoiceLin

下面是抛出
ConcurrentModificationException
的java代码

下面是正在声明的列表

List<BrokerInvoiceLineItem> brokerInvoiceLineItems= new ArrayList<BrokerInvoiceLineItem>();
            brokerInvoiceLineItems=brokerInvoice.getLineItems();
现在的问题是,如果brokerInvoiceLineItems不为null,那么对于第一次迭代,它将进入循环,并且名为isAnyValid的变量的值设置为true,但是一旦第一次迭代结束,对于第二次迭代,它将进入(BrokerInvoiceLineItem BrokerInvoiceLineItem:brokerInvoiceLineItems)的行
{
然后它不会进入下一行,它会抛出并发修改exeption

这意味着它必须在迭代时修改BooCuffeleInItIts项大小。这可能发生在<代码> FETCHeNeNo.OLDCFANADAMEST/<代码>中,所以我考虑复制BraseCuffiCeleIn项并修改副本。因此,请告诉我如何将副本传递到<代码> FETCHeNAND OLDCFANDAMED(BooCuffiCeleInItIt)。


另外,请建议如何使用copyonwriteArray列表以避免此类错误

您应该创建一个新的ArrayList,并向其中添加以前ArrayList对象的所有元素

ArrayList<BrokerInvoiceLineItem> otherList = new ArrayList<BrokerInvoiceLineItem>();
otherList.addAll(brokerInvoiceLineItems);
ArrayList otherList=新建ArrayList();
otherList.addAll(brokerInvoiceLineItems);
注意:如果您更改了另一个类似的for语句:

for(int i=0;i<brokerInvoiceLineItems.size();i++){

用于(int i=0;i我假设您正在修改方法
fetchNewAndOldCFandAmend
中的
brokerInvoiceLineItems
。您可以使用a而不是ArrayList。这允许您迭代列表,同时更新它。这会带来一些成本,因为每次添加内容时都会创建一个新数组。sample代码如下所示:

    // Member field declaration
    List<BrokerInvoiceLineItem> brokerInvoiceLineItems;

    // Retrieve the list of objects
    List<BrokerInvoiceLineItem> items = brokerInvoice.getLineItems();
    if (items == null) {
        items = brokerInvoiceHome.findLineitemsByInvoiceId(brokerInvoice.getId());
    }

    // Initialize your member variable to be a 
    // CopyOnWriteArrayList with the above elements
    brokerInvoiceLineItems = new CopyOnWriteArrayList<>(items);

    // Iterate over the elements and possibly update the list from
    // the fetchNewAndOldCFandAmend method
    for (BrokerInvoiceLineItem brokerInvoiceLineItem : brokerInvoiceLineItems) {
        if (fetchNewAndOldCFandAmend(brokerInvoiceLineItem)) {
            if (!isAnyValid)
                isAnyValid = true;
        }
    }
//成员字段声明
列出行项目;
//检索对象列表
List items=brokerInvoice.getLineItems();
if(items==null){
items=brokerInvoiceHome.FindLineItemsByVoiceId(brokerInvoice.getId());
}
//将成员变量初始化为
//具有上述元素的CopyOnWriteArrayList
brokerInvoiceLineItems=新的CopyOnWriteArrayList(项目);
//迭代元素,并可能从更新列表
//FetchNewandOldCfandMend方法
对于(BrokerInvoiceLineItem BrokerInvoiceLineItem:brokerInvoiceLineItems){
if(获取新的和旧的CfandMend(brokerInvoiceLineItem)){
如果(!isAnyValid)
isAnyValid=true;
}
}
我的代码假设您有一个存储BrokerInvoiceLineItem列表的类,它的初始化是在构造函数中进行的


通常,对列表进行迭代并调用另一个更新列表的方法是一个坏主意。您可以使用迭代器遍历列表并删除某些元素。您的
fetchNewAndOldCFandAmend
可能可以用于指示是否应从列表中删除当前项,并调用迭代器的remove方法。

我想您已经明白了删除
brokerInvoiceLineItems
的某些项目时,会出现异常

要避免此异常,请使用迭代器

Iterator<BrokerInvoiceLineItem> iterator = brokerInvoiceLineItems.iterator();
while(iterator.hasNext()) {
  BrokerInvoiceLineItem brokerInvoiceLineItem = iterator.next();
    // your code
}

使用,Collections.unmodifiableList(brokerInvoiceLineItems)怎么样;你能发布你的
brokerInvoice.getLineItems
brokerInvoiceHome.FindLineItemsByVoiceId
方法吗?那么你能转换我上面的代码片段并给我看一下我所做的for循环部分吗?只要用第一个代码片段替换for循环就行了。如果(fetchNewAndOldCFandAmend(brokerInvoiceLineItem)){我将如何克服这个问题我想你是在该方法的列表中添加或删除项目。一个好的做法是在迭代列表时不修改列表,因此第一种方法(将列表复制到另一个列表)如果可能的话,你可以在我上面的代码中显示它,这将是一个很大的帮助。你可以添加更多关于如何使用这个类的详细信息,以及如何从两个brokerInvoice对象检索列表吗?是现有元素的新副本或它们使用的基础列表?
    // Member field declaration
    List<BrokerInvoiceLineItem> brokerInvoiceLineItems;

    // Retrieve the list of objects
    List<BrokerInvoiceLineItem> items = brokerInvoice.getLineItems();
    if (items == null) {
        items = brokerInvoiceHome.findLineitemsByInvoiceId(brokerInvoice.getId());
    }

    // Initialize your member variable to be a 
    // CopyOnWriteArrayList with the above elements
    brokerInvoiceLineItems = new CopyOnWriteArrayList<>(items);

    // Iterate over the elements and possibly update the list from
    // the fetchNewAndOldCFandAmend method
    for (BrokerInvoiceLineItem brokerInvoiceLineItem : brokerInvoiceLineItems) {
        if (fetchNewAndOldCFandAmend(brokerInvoiceLineItem)) {
            if (!isAnyValid)
                isAnyValid = true;
        }
    }
Iterator<BrokerInvoiceLineItem> iterator = brokerInvoiceLineItems.iterator();
while(iterator.hasNext()) {
  BrokerInvoiceLineItem brokerInvoiceLineItem = iterator.next();
    // your code
}
Iterator<BrokerInvoiceLineItem> iterator = brokerInvoiceLineItems.iterator();
while(iterator.hasNext()) {
  BrokerInvoiceLineItem brokerInvoiceLineItem = iterator.next();
  if (fetchNewAndOldCFandAmend(brokerInvoiceLineItem)) {
    if (!isAnyValid)
      isAnyValid = true;
  }
}