Java 在迭代时向列表添加元素时出现ConcurrentModificationException

Java 在迭代时向列表添加元素时出现ConcurrentModificationException,java,android,Java,Android,我的适配器中有此代码,它显示学校列表。还有一个搜索过滤器。每当搜索筛选器具有值时,列表必须显示包含搜索筛选器字母的学校。这是我的密码- public boolean refreshAdapter() { List<School> schools = cache().getSchools(); if (schoolList != null && !schoolList.isEmpty()) { schoolList

我的适配器中有此代码,它显示学校列表。还有一个搜索过滤器。每当搜索筛选器具有值时,列表必须显示包含搜索筛选器字母的学校。这是我的密码-

public boolean refreshAdapter() {
        List<School> schools = cache().getSchools();
        if (schoolList != null && !schoolList.isEmpty()) {
            schoolList .clear();
        }

        schoolList = schools;

        for (School school: schoolList) {

            String name = school.getName();
            String address = vehicle.getAddress();

            if (name.contains(searchFilterText)|| address.contains(searchFilterText)) {
                schoolList.add(school);
            }
        }
        notifyDataSetChanged();
        if (schoolList!= null) {
            return schoolList.isEmpty();
        }
        return false;
    }
公共布尔刷新适配器(){
List schools=cache().getSchools();
if(schoolList!=null&&!schoolList.isEmpty()){
学校名单;
}
学校名单=学校;
(学校:学校名单){
字符串名称=school.getName();
字符串地址=vehicle.getAddress();
if(name.contains(searchFilterText)| | address.contains(searchFilterText)){
学校列表。添加(学校);
}
}
notifyDataSetChanged();
如果(学校列表!=null){
返回schoolList.isEmpty();
}
返回false;
}

如何在没有并发修改异常的情况下运行此代码?我尝试使用ListIterator,但没有帮到我,

ConcurrentModificationException是因为在遍历该列表的过程中,
学校列表
列表正在被修改。另一种方法是迭代
学校
列表,并向
学校列表
添加内容,将迭代列表与修改列表分开:

schoolList = new ArrayList<>();

for (School school: schools) {

    String name = school.getName();
    String address = vehicle.getAddress();

    if (name.contains(searchFilterText)|| address.contains(searchFilterText)) {
        schoolList.add(school);
    }
}

根据代码的当前状态,您似乎将向
学校列表
中重新添加元素,因为它已经包含这些元素,因此您要迭代这些元素。上面的代码示例将生成只包含匹配元素的列表。如果希望将匹配元素重新添加到
学校列表中,如原问题所示,您可以替换第一个示例中的以下行

schoolList = new ArrayList<>();
迭代1:

matching school A
matching school A    <-- Current element of iteration
matching school A    <-- [newly added element]
匹配学校A

匹配学校AConcurrentModificationException
的产生是因为
schoolList
列表在迭代该列表的过程中被修改。另一种方法是迭代
学校
列表,并向
学校列表
添加内容,将迭代列表与修改列表分开:

schoolList = new ArrayList<>();

for (School school: schools) {

    String name = school.getName();
    String address = vehicle.getAddress();

    if (name.contains(searchFilterText)|| address.contains(searchFilterText)) {
        schoolList.add(school);
    }
}

根据代码的当前状态,您似乎将向
学校列表
中重新添加元素,因为它已经包含这些元素,因此您要迭代这些元素。上面的代码示例将生成只包含匹配元素的列表。如果希望将匹配元素重新添加到
学校列表中,如原问题所示,您可以替换第一个示例中的以下行

schoolList = new ArrayList<>();
迭代1:

matching school A
matching school A    <-- Current element of iteration
matching school A    <-- [newly added element]
匹配学校A

匹配学校A您将获得
ConcurrentModificationException
-s,因为您在列表中添加内容时正在迭代。一般来说,这是被禁止的,因为通过迭代添加内容是令人困惑的。在某些情况下,程序员希望迭代遍历最近添加的项,有时不是。所以java强迫我们显式地做这两件事中的任何一件

您可以使用存储要添加到列表中的项目的临时列表来修复它

步骤1:查找要添加的项目。
您将获得
ConcurrentModificationException
-s,因为您在列表中添加内容时正在迭代。一般来说,这是被禁止的,因为通过迭代添加内容是令人困惑的。在某些情况下,程序员希望迭代遍历最近添加的项,有时不是。所以java强迫我们显式地做这两件事中的任何一件

您可以使用存储要添加到列表中的项目的临时列表来修复它

步骤1:查找要添加的项目。
请注意,发生此异常是因为在迭代集合时不能向集合中添加元素。你是否对
学校
学校名单
感到困惑?给他们更合理的名字会有很大帮助

要正确执行此操作,您必须构建一个新的筛选列表(我对更改的行进行了注释)

//这是新的筛选列表
schoolList=newarraylist();
//迭代原始列表
(学校:学校){
字符串名称=school.getName();
字符串地址=vehicle.getAddress();
if(name.contains(searchFilterText)| | address.contains(searchFilterText)){
//将其添加到筛选列表中
学校列表。添加(学校);
}
}

请注意,出现此异常是因为在迭代集合时,不能向集合中添加元素。你是否对
学校
学校名单
感到困惑?给他们更合理的名字会有很大帮助

要正确执行此操作,您必须构建一个新的筛选列表(我对更改的行进行了注释)

//这是新的筛选列表
schoolList=newarraylist();
//迭代原始列表
(学校:学校){
字符串名称=school.getName();
字符串地址=vehicle.getAddress();
if(name.contains(searchFilterText)| | address.contains(searchFilterText)){
//将其添加到筛选列表中
学校列表。添加(学校);
}
}

您试图创建的循环的目的是什么?通过阅读代码,您似乎正在尝试按与搜索字符串匹配的名称或地址筛选列表,对吗?@JustinAlbano是的,我正在尝试按名称或地址筛选循环中的列表您尝试创建的循环的目的是什么?阅读代码后,您似乎正在尝试按与搜索字符串匹配的名称或地址筛选列表,对吗?@JustinAlbano是的,我正在尝试按循环中的名称或地址筛选列表
matching school A
matching school A
matching school A    <-- Current element of iteration
matching school A    <-- [newly added element]
List<School> tempSchoolList = new ArrayList<>(); // this is the new list

// most of the things below comes from the original code
schoolList = schools;

for (School school: schoolList) {

    String name = school.getName();
    String address = vehicle.getAddress();
    if (name.contains(searchFilterText)|| address.contains(searchFilterText)) {
        tempSchoolList.add(school); // add the new list to the temp school list
    }
}
schoolList.addAll(tempSchoolList);
    // this is the new filtered list
    schoolList = new ArrayList<>();

    // iterate the original list
    for (School school: schools) {

        String name = school.getName();
        String address = vehicle.getAddress();

        if (name.contains(searchFilterText)|| address.contains(searchFilterText)) {
             // add it to filtered list
            schoolList.add(school);
        }
    }