如何使用循环从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);
}

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...