Java 中是否有公认的在迭代列表时删除列表元素的最佳实践?

发布于 2024-11-05 17:14:40 字数 341 浏览 7 评论 0原文

我发现在执行此操作时避免 ConcurrentModificationException 的最佳方法存在相互矛盾的建议:

    List<Apple> Apples = appleCart.getApples();
    for (Apple apple : Apples)
    {
        delete(apple);
    }

我倾向于使用 Iterator 代替 List code> 并调用其 remove 方法。

这在这里最有意义吗?

I'm finding conflicting advice over the best way to avoid a ConcurrentModificationException while doing this:

    List<Apple> Apples = appleCart.getApples();
    for (Apple apple : Apples)
    {
        delete(apple);
    }

I'm leaning towards using an Iterator in place of a List and calling its remove method.

Does that make the most sense here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

旧伤还要旧人安 2024-11-12 17:14:40

是的,使用迭代器。然后你可以使用它的删除方法。

  for (Iterator<Apple> appleIterator = Apples.iterator(); appleIterator.hasNext();) {
     Apple apple = appleIterator.next();
     if (apple.isTart()) {
        appleIterator.remove();
     }
  }
}

Yes, use an Iterator. Then you could use its remove method.

  for (Iterator<Apple> appleIterator = Apples.iterator(); appleIterator.hasNext();) {
     Apple apple = appleIterator.next();
     if (apple.isTart()) {
        appleIterator.remove();
     }
  }
}
摇划花蜜的午后 2024-11-12 17:14:40

如果您收到 ConcurrentModificationException,则您可能有多个线程。

因此,完整的答案包括使用 Iterator.remove() 和同步对集合的访问。

例如(其中lock由可能修改列表的所有线程同步):

synchronized ( lock ) {
   List<Apple> apples = appleCart.getApples();
   for ( Iterator<Apple> it = apples.iterator(); it.hasNext(); )
   {
      Apple a = it.next(); 
      if ( a.hasWorm() ) {
         it.remove();
      }
   }
}

If you're getting a ConcurrentModificationException, you likely have multiple threads.

So the full answer includes both using Iterator.remove() and synchronizing access to the collection.

For example (where lock is synchronized on by all threads that may modify the list):

synchronized ( lock ) {
   List<Apple> apples = appleCart.getApples();
   for ( Iterator<Apple> it = apples.iterator(); it.hasNext(); )
   {
      Apple a = it.next(); 
      if ( a.hasWorm() ) {
         it.remove();
      }
   }
}
本宫微胖 2024-11-12 17:14:40
List<Apple> apples = appleCart.getApples();
for (Iterator<Apple> appleIterator = apples.iterator(); appleIterator.hasNext();)
{
   Apple apple = appleIterator.next();
   if ( apple.isYucky() ) {
     appleIterator.remove();
   }
}
List<Apple> apples = appleCart.getApples();
for (Iterator<Apple> appleIterator = apples.iterator(); appleIterator.hasNext();)
{
   Apple apple = appleIterator.next();
   if ( apple.isYucky() ) {
     appleIterator.remove();
   }
}
唠甜嗑 2024-11-12 17:14:40

您可以保留要删除的项目列表,然后在循环后删除它们:

List<Apple> apples = appleCart.getApples();
List<Apple> badApples = new ArrayList<Apple>();
for (Apple apple : apples) {
    if (apple.isBad()) {
        badApples.add(apple);
    } else {

    eat(apple);
}

apples.removeAll(badApples);

You could keep a list of items to remove and then remove them after the loop:

List<Apple> apples = appleCart.getApples();
List<Apple> badApples = new ArrayList<Apple>();
for (Apple apple : apples) {
    if (apple.isBad()) {
        badApples.add(apple);
    } else {

    eat(apple);
}

apples.removeAll(badApples);
这样的小城市 2024-11-12 17:14:40

从 Java 8 开始,您现在可以执行以下操作:
<代码>
apples.removeIf(苹果 -> apple.equals(this))

Since Java 8 you can now do this:

apples.removeIf(apple -> apple.equals(this))

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文