微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用循环从Java中删除队列中的元素

我有这样的数据结构:

BlockingQueue mailBox = new LinkedBlockingQueue();

我正在尝试这样做:

for(Mail mail: mailBox)
{
    if(badNews(mail))
    {
        mailBox.remove(mail);
    }
}

显然循环的内容会干扰边界并触发错误,所以我通常会这样做:

for(int i = 0;  i < mailBox.size(); i++)
{
    if(badNews(mailBox.get(i)))
    {
        mailBox.remove(i);
        i--;
    }
}

但遗憾的是BlockingQueue没有按索引获取删除元素的功能,所以我卡住了.有任何想法吗?

编辑 – 一些澄清:
我的目标之一是保持相同的顺序,从头部弹出并将其放回尾部是不好的.此外,虽然没有其他线程会从邮箱中删除邮件,但是它们会添加到邮箱中,因此我不希望处于删除算法的中间,让某人向我发送邮件,然后发生异常.

提前致谢!

解决方法

您可以在队列中完成所有元素,直到队列中的所有元素为止,然后才能使用 poll和p̶u̶s̶h̶ offer.这是一个例子:
Mail firstMail = mailBox.peek();
Mail currentMail = mailBox.pop();
while (true) {
    //a base condition to stop the loop
    Mail tempMail = mailBox.peek();
    if (tempMail == null || tempMail.equals(firstMail)) {
        mailBox.offer(currentMail);
        break;
    }
    //if there's nothing wrong with the current mail,then re add to mailBox
    if (!badNews(currentMail)) {
        mailBox.offer(currentMail);
    }
    currentMail = mailBox.poll();
}

请注意,只有在单个线程中执行此代码并且没有其他线程从此队列中删除项目时,此方法才有效.

也许您需要检查是否真的要轮询或从BlockingQueue中获取元素.提供和放置类似.

更多信息:

> Java BlockingQueue take() vs poll()
> LinkedBlockingQueue put vs offer

另一种不那么错误方法是使用临时集合,不一定是并发的,并将您仍需要的元素存储在队列中.这是一个启动示例:

List<Mail> mailListTemp = new ArrayList<>();
while (mailBox.peek() != null) {
    Mail mail = mailBox.take();
    if (!badNews(mail)) {
        mailListTemp.add(mail);
    }
}
for (Mail mail : mailListTemp) {
    mailBox.offer(mail);
}

原文地址:https://www.jb51.cc/java/128362.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐