繁体   English   中英

在迭代器期间从 ArrayList 中删除多个项目

[英]Remove multiple items from ArrayList during iterator

在使用迭代器迭代 ArrayList 时从 ArrayList 中删除多个项目是否安全?

Iterator<String> iterator = nameList.iterator();
 while(iterator.hasNext()){
     String s = iterator.next();
     List<String> list = work(s);
     for (String s1 : list) {
        nameList.remove(s1);   
    }
}

work()方法返回在 while 循环运行期间应从 nameList 中删除的名称列表。

不,它不安全,可以抛出ConcurrentModificationException 您可以在临时List收集要删除的所有元素,然后在while循环之后调用list.removeAll(tmpList)来执行删除。

Iterator<String> iterator = nameList.iterator();
List<String> removed = new ArrayList<>();
while(iterator.hasNext()){
    String s = iterator.next();
    removed.addAll(work(s));
}
list.removeAll(removed);

我意识到这可能效率较低,因为你可能会在String上调用work(s)应该已经从List删除了。 这可以通过将tempList更改为Set来改进,并且只调用不在Set中的Stringwork(s)

Iterator<String> iterator = nameList.iterator();
Set<String> removed = new HashSet<>();
while(iterator.hasNext()){
    String s = iterator.next();
    if (!removed.contains(s)) {
        removed.addAll(work(s));
    }
}
list.removeAll(removed);

如果使用故障安全的ListIterator,则可以实现逻辑。 以下是一个基本示例:

Set<String> removed = new HashSet<>();
    ArrayList<String> nameList = new ArrayList<String>();

            ListIterator<String> iterator = nameList.listIterator();
             while(iterator.hasNext()){
                 String s = iterator.next();
                 if (!removed.contains(s)) {
        removed.addAll(work(s));
    }

            }


 nameList.removeAll(removed);
                 System.out.println(nameList);

根据您的逻辑,您必须考虑性能。 如果性能不是一个因素,您可以继续通过ListIterator从列表中添加/删除。

如前面的答案所述,从迭代列表中删除项目并不安全。 这是抛出ConcurrentModificationException的代码:

List<String> list = new ArrayList<>(Arrays.asList("1", "2", "3"));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String s = iterator.next();
    list.remove("1");
}

您可以使用Iterator.remove() (而不是nameList.remove(s) )。

Iterator<String> iterator = nameList.iterator();
while(iterator.hasNext()){
    String s = iterator.next();
    iterator.remove();
}

还要考虑nameList.clear()nameList.removeAll(elementsToRemove)

迭代器在对其底层 collections 进行任何修改后通常无效,除非通过迭代器本身。 - 当我对列表进行排序时,它的迭代器会发生什么?

https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM