当前位置: 首页 > 面试题库 >

遍历Collection,避免在循环中删除对象时避免ConcurrentModificationException

孟沛
2023-03-14
问题内容

我们都知道您由于以下原因而无法执行以下操作ConcurrentModificationException

for (Object i : l) {
    if (condition(i)) {
        l.remove(i);
    }
}

但这显然有时有效,但并非总是如此。这是一些特定的代码:

public static void main(String[] args) {
    Collection<Integer> l = new ArrayList<>();

    for (int i = 0; i < 10; ++i) {
        l.add(4);
        l.add(5);
        l.add(6);
    }

    for (int i : l) {
        if (i == 5) {
            l.remove(i);
        }
    }

    System.out.println(l);
}

当然,这导致:

Exception in thread "main" java.util.ConcurrentModificationException

即使没有多个线程。无论如何。

解决此问题的最佳方法是什么?如何在不引发此异常的情况下循环地从集合中删除项目?

我还在Collection这里使用任意值,不一定是an ArrayList,因此您不能依赖get


问题答案:

Iterator.remove() 是安全的,您可以这样使用它:

List<String> list = new ArrayList<>();

// This is a clever way to create the iterator and call iterator.hasNext() like
// you would do in a while-loop. It would be the same as doing:
//     Iterator<String> iterator = list.iterator();
//     while (iterator.hasNext()) {
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
    String string = iterator.next();
    if (string.isEmpty()) {
        // Remove the current element from the iterator and the list.
        iterator.remove();
    }
}

注意,这Iterator.remove()是在迭代过程中修改集合的唯一安全方法。如果在进行迭代时以任何其他方式修改了基础集合,则行为未指定。

来源:docs.oracle>收集接口

同样,如果您有个ListIterator并想要添加项目,则可以使用ListIterator#add,出于相同的原因Iterator#remove ,它可以允许使用。

你的情况,你想从列表中删除,但同样的限制,如果想put成为一个Map在迭代的内容。



 类似资料:
  • 问题内容: 我有一个要迭代的ArrayList。遍历它时,我必须同时删除元素。显然,这引发了。 解决此问题的最佳实践是什么?我应该先克隆列表吗? 我删除的不是循环本身的元素,而是代码的另一部分。 我的代码如下所示: 可能打电话; 问题答案: 两种选择: 创建要删除的值的列表,将其添加到循环中的列表中,然后在最后调用 在迭代器本身上使用该方法。请注意,这意味着你不能使用增强的for循环。 作为第二个

  • 问题内容: 我尝试使用MVP范例构建Webapp。因为我希望API干净并且使所有内容易于测试,所以我尝试通过Contructor Injection注入所有可能的内容。现在,我到了一个具有多个文本字段的视图。当数据库中有值时,演示者将填充这些文本字段,因此我的演示者需要视图的引用,但是vie显然也需要演示者的引用。CDI告诉我,由于循环依赖性,无法将Presenter注入视图。是否有可能避免通过s

  • 问题内容: 我对PMD规则有疑问。这是一些示例代码: PMD在代码中的标记位置给了我上述违反规则的权限。我应该如何创建一个类的 n个 实例而不在循环内创建它们? 我知道某些PMD规则存在争议(例如 onlyOneExit 规则)。但是到目前为止,我至少了解它们背​​后的想法。我不明白这条规则背后的原因。有人可以帮我吗? 问题答案: 对于您的特定用例,由于在循环 后 保留对新对象的引用,因此没有任何

  • 问题内容: 我的页面包含一堆表格。我在外循环中遍历表,然后在内循环中遍历表中的每一行。一切正常。但是某些页面具有“下一步”按钮。当我在完成页面后添加代码以单击该代码时,则在遍历表的各行时开始获取StaleElementReferenceException。 这是代码: 我不明白的是,为什么过时的因素根本没有发生?该页面在循环过程中没有更改,我一直等到所有元素都提取完之后。如何避免StaleElem

  • 从我的main开始,我将启动两个线程,称为producer和consumer。两者都包含循环。生产者循环是UDP服务器,因此不需要Hibernate。我的问题出在消费者方面。使用者循环将对象从链接队列中移除,并将其传递给一个函数进行进一步处理。根据研究,在循环中使用线程Hibernate不是一个好的实践,因为有时O/S在设定时间结束时不会释放。如果我删除线程Hibernate,当应用程序是理想的,

  • 问题内容: 堆垛机。我一直在网站上搜索我的问题,但没有找到我想要的东西。我坚持下面的代码: 得到了一个不错的数组列表,但是如果我在ArrayList中添加更多“ newUsers”,它们似乎会相互覆盖。我不想创建一个newUser1,newUser2对象,因为稍后在我的程序中,我必须能够直接从该程序添加新用户。 如何实现呢? ValidateUser: } 问题答案: 如果我理解正确,那么您是以这