JAVA中怎么继承interfere_如何使用循環從Java中刪除隊列中的元素

I have a data structure like this:

我有這樣的數據結構:

BlockingQueue mailbox = new LinkedBlockingQueue();

BlockingQueue mailbox = new LinkedBlockingQueue();

I'm trying to do this:

我正在嘗試這樣做:

for(Mail mail: mailbox)

{

if(badNews(mail))

{

mailbox.remove(mail);

}

}

Obviously the contents of the loop interfere with the bounds and a error is triggered, so I would normally do this:

顯然循環的內容會干擾邊界並觸發錯誤,所以我通常會這樣做:

for(int i = 0; i < mailbox.size(); i++)

{

if(badNews(mailbox.get(i)))

{

mailbox.remove(i);

i--;

}

}

But sadly BlockingQueue's don't have a function to get or remove an element by index, so I'm stuck. Any ideas?

但遺憾的是BlockingQueue沒有按索引獲取或刪除元素的功能,所以我卡住了。有任何想法嗎?

Edit - A few clarifications: One of my goals is the maintain the same ordering so popping from the head and putting it back into the tail is no good. Also, although no other threads will remove mail from a mailbox, they will add to it, so I don't want to be in the middle of an removal algorithm, have someone send me mail, and then have an exception occur.

編輯 - 一些澄清:我的目標之一是保持相同的順序,從頭部彈出並將其放回尾部是不好的。此外,雖然沒有其他線程會從郵箱中刪除郵件,但是它們會添加到郵箱中,因此我不希望處於刪除算法的中間,讓某人向我發送郵件,然后發生異常。

Thanks in advance!

提前致謝!

3 个解决方案

#1

3

You may p̶o̶p̶ poll and p̶u̶s̶h̶ offer all the elements in your queue until you make a complete loop over your queue. Here's an example:

您可以進行輪詢,並提示隊列中的所有元素,直到您對隊列進行完整循環。這是一個例子:

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();

}

Note that this approach will work only if this code is executed in a single thread and there's no other thread that removes items from this queue.

請注意,只有在單個線程中執行此代碼並且沒有其他線程從此隊列中刪除項目時,此方法才有效。

Maybe you need to check if you really want to poll or take the elements from the BlockingQueue. Similar for offer and put.

也許您需要檢查是否真的要輪詢或從BlockingQueue中獲取元素。提供和投入類似。

More info:

更多信息:

Another less buggy approach is using a temporary collection, not necessarily concurrent, and store the elements you still need in the queue. Here's a kickoff example:

另一種不那么錯誤的方法是使用臨時集合,不一定是並發的,並將您仍需要的元素存儲在隊列中。這是一個啟動示例:

List mailListTemp = new ArrayList<>();

while (mailbox.peek() != null) {

Mail mail = mailbox.take();

if (!badNews(mail)) {

mailListTemp.add(mail);

}

}

for (Mail mail : mailListTemp) {

mailbox.offer(mail);

}

#2

0

I looked over the solutions posted and I think I found a version that serves my purposes. What do you think about this one?

我查看了發布的解決方案,我想我發現了一個符合我目的的版本。你覺得這個怎么樣?

int size = mailbox.size();

for(int i = 0; i < size; i++)

{

Mail currentMail = mailbox.poll();

if (!badNews(currentMail))

mailbox.offer(currentMail);

}

Edit: A new solution that may be problem free. What you guys think?

編輯:一個可能沒有問題的新解決方案。你們覺得怎么樣?

while(true)

{

boolean badNewRemains = false;

for(Mail mail: mailbox)

{

if(badNews(mail))

{

badNewRemains = true;

mailbox.remove(mail);

break;

}

}

if(!badNewRemains)

break;

}

#3

0

You can easily implement queue for your need. And you will need to, if API provided doesn't have such features.

您可以根據需要輕松實現隊列。如果提供的API沒有這樣的功能,您將需要。

One like:

一個像:

import java.util.Iterator;

import java.util.LinkedList;

class Mail {

boolean badMail;

}

class MailQueue {

private LinkedList backingQueue = new LinkedList<>();

private final Object lock = new Object();

public void push(Mail mail){

synchronized (lock) {

backingQueue.addLast(mail);

if(backingQueue.size() == 1){

// this is only element in queue, i.e. queue was empty before, so invoke if any thread waiting for mails in queue.

lock.notify();

}

}

}

public Mail pop() throws InterruptedException{

synchronized (lock) {

while(backingQueue.isEmpty()){

// no elements in queue, wait.

lock.wait();

}

return backingQueue.removeFirst();

}

}

public boolean removeBadMailsInstantly() {

synchronized (lock) {

boolean removed = false;

Iterator iterator = backingQueue.iterator();

while(iterator.hasNext()){

Mail mail = iterator.next();

if(mail.badMail){

iterator.remove();

removed = true;

}

}

return removed;

}

}

}

The implemented queue will be thread-safe, whether push or pop. Also you can edit queue for more operations. And it will allow to access removeBadMailsInstantly method by multiple threads (thread-safe). And you will also learn concepts of multithreading.

無論是push還是pop,實現的隊列都是線程安全的。您還可以編輯隊列以進行更多操作。並且它允許多個線程訪問removeBadMailsInstantly方法(線程安全)。您還將學習多線程的概念。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值