如何在Java中的for循环内向ArrayList添加元素而不出现ConcurrentModificationException异常

3

我有一个Java Spring MVC Web应用程序。我正在尝试遍历一个ArrayList,并根据某些条件向列表中添加新元素。我使用以下代码:

List<LocationHourListHB> locationHoursList = new ArrayList<LocationHourListHB>();
List<HoursTO> hourList = listHoursByEntityId(applicationId, siteId, locationId);
for (HoursTO hoursTO : hourList) 
{
    if(locationHoursList.size() == 0)
    {
        LocationHourListHB locationHourListHB = new LocationHourListHB();
        locationHourListHB.setStartTIme(hoursTO.getStartTime());
        locationHourListHB.setEndTime(hoursTO.getEndTime());
        locationHoursList.add(locationHourListHB);
        break;
    }
    for (LocationHourListHB locationHour : locationHoursList) 
    {
        if(hoursTO.getStartTime().equalsIgnoreCase(locationHour.getStartTIme()) && hoursTO.getEndTime().equalsIgnoreCase(locationHour.getEndTime()))
        {
            break;
        }
        else
        {
            LocationHourListHB locationHourListHB = new LocationHourListHB();
            locationHourListHB.setStartTIme(hoursTO.getStartTime());
            locationHourListHB.setEndTime(hoursTO.getEndTime());
            locationHoursList.add(locationHourListHB);
        }
    }
}
}

但是执行这个代码会抛出一个 "concurrent modification exception" 异常。我做了一些研究,发现可以使用 "iterator" 或 "list iterator" 来解决这个问题。有没有一个好的例子可以跟随使用 "list iterator" 来解决我的问题。或者有更好的解决方案可以帮助我。

我尝试了以下代码:

for (HoursTO hoursTO : hourList) 
{
    if(locationHoursList.size() == 0)
    {
        LocationHourListHB locationHourListHB = new LocationHourListHB();
        locationHourListHB.setStartTIme(hoursTO.getStartTime());
        locationHourListHB.setEndTime(hoursTO.getEndTime());
        locationHoursList.add(locationHourListHB);
        }
        ListIterator<LocationHourListHB> iter = locationHoursList.listIterator();
        while(iter.hasNext())
        {
        if(!(iter.next().getStartTIme().equalsIgnoreCase(hoursTO.getStartTime()) && iter.next().getEndTime().equalsIgnoreCase(hoursTO.getEndTime())))
        {
            LocationHourListHB locationHourListHB = new LocationHourListHB();
            locationHourListHB.setStartTIme(hoursTO.getStartTime());
            locationHourListHB.setEndTime(hoursTO.getEndTime());
            iter.add(locationHourListHB);
        }
    }
}

但是如果出现NoSuchElementException异常


1
不要多次使用iter.next(),请查看我的更新答案。 - HPCS
2个回答

2
您可以这样使用ListIterator:
ArrayList<LocationHourListHB> locationHoursList = new ArrayList<LocationHourListHB>();

ListIterator<LocationHourListHB> iterator = locationHoursList.listIterator();

while(iterator.hasNext(){
LocationHourListHB locationHour = iterator.next()
  if(hoursTO.getStartTime().equalsIgnoreCase(locationHour.getStartTIme()) && hoursTO.getEndTime().equalsIgnoreCase(locationHour.getEndTime()))
        {
            break;
        }
        else
        {
            LocationHourListHB locationHourListHB = new LocationHourListHB();
            locationHourListHB.setStartTIme(hoursTO.getStartTime());
            locationHourListHB.setEndTime(hoursTO.getEndTime());
            iterator.add(locationHourListHB);
        }

}

@Geo Thomas,我看到你试图编辑答案,但更好的方法是写在评论中或更新你自己的问题。你发送到编辑器的代码存在一个问题,即在 iterator.hasNext() 之后多次调用 iterator.next()。每次调用 iterator.next() 都会返回列表中的下一个元素,而不是相同的元素!

你应该像这样使用:

LocationHourListHB locationHour = iterator.next()

接着在代码中使用locationHour。


那次编辑是错误的。感谢更新。 - Geo Thomas

1

如果您在迭代时尝试向列表中添加内容,将会得到相同的异常,因此您不能使用迭代器。迭代器上没有添加方法,请注意保留HTML标签。

ListIterator有一个添加方法,可以在下一个元素之前添加新的项目。

    List<String> list = new ArrayList<>();
    list.add("one");
    list.add("two");
    ListIterator<String> iterator = list.listIterator();
    while (iterator.hasNext()) {
        String value = iterator.next();
        if (value.equals("one")) {
            iterator.add("three");
        }
    }
    System.out.println(list);  // prints [one, three, two]

如果需要在列表末尾添加内容,请使用第二个列表,并在循环后添加它们。
    List<String> list = new ArrayList<>();
    List<String> newValues = new ArrayList<>();
    list.add("one");
    list.add("two");
    for (String value : list) {
        if (value.equals("one")) {
            newValues.add("three");
        }
    }
    list.addAll(newValues);
    System.out.println(list);  // prints [one, two, three]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接