如何在for循环内的Java中将元素添加到arraylist中而没有并发修改异常

时间:2018-12-08 13:13:34

标签: java collections iterator

我有一个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。我进行了一些研究,发现可以使用iteratorlist 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

2 个答案:

答案 0 :(得分: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()mutltiplle次。每次调用iterator.next()时,它将返回列表中的下一个元素,而不是同一元素!

您应该这样使用它:

LocationHourListHB locationHour = iterator.next()

然后在代码locationHour中使用。

答案 1 :(得分:1)

您不能使用迭代器,如果尝试在迭代时添加到列表中,则会遇到相同的异常,并且迭代器上没有add方法。

ListIterator有一个add方法,可将新项目添加到下一个项目之前。

    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]