How to remove items from a queue in Java using a loop

I have a data structure like this:

BlockingQueue mailbox = new LinkedBlockingQueue ();

I am trying to do this:

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

Obviously, the contents of the loop interfere with the boundaries and an error occurs, so I usually do this:

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

But unfortunately, BlockingQueue does not have a function to retrieve or delete an item by index, so I'm stuck. Any ideas?

Edit - A few clarifications: One of my goals is to maintain the same order as jumping out of my head and putting it back in the tail is not good. In addition, although no other threads will delete mail from the mailbox, they will be added to it, so I do not want to be in the middle of the deletion algorithm, someone will send me mail, and then an exception will occur.

Thanks in advance!

+7
java loops blockingqueue
source share
3 answers

You can p̶o̶p̶ poll and p̶u̶s̶h̶ offer all the items in your queue until you complete the cycle on your queue. Here is 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 nothing wrong with the current mail, then re add to mailbox if (!badNews(currentMail)) { mailbox.offer(currentMail); } currentMail = mailbox.poll(); } 

Please note that this approach will only work if this code is executed in one thread and there is no other thread that removes items from this queue.

Perhaps you need to check if you really want to poll or take items from BlockingQueue. Similar offers and offers.

Additional Information:

  • Java BlockingQueue take () vs poll ()
  • LinkedBlockingQueue puts vs offer

Another less flawed approach is to use a temporary collection, not necessarily parallel, and keep the items that you still need in the queue. Here is an example run:

 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); } 
+3
source share

I looked at the hosted solutions, and I think I found a version that serves my purpose. What do you think about this?

 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 could be no problem. What do you guys think?

 while(true) { boolean badNewRemains = false; for(Mail mail: mailbox) { if(badNews(mail)) { badNewRemains = true; mailbox.remove(mail); break; } } if(!badNewRemains) break; } 
0
source share

You can easily implement a queue for your needs. And you will need it if the provided API does not have such functions.

One of them:

 import java.util.Iterator; import java.util.LinkedList; class Mail { boolean badMail; } class MailQueue { private LinkedList<Mail> 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, ie 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<Mail> 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. You can also edit the queue for more operations. And this will allow you to access the removeBadMailsInstantly method removeBadMailsInstantly multiple threads (thread safe). And you will also learn the concepts of multithreading.

0
source share

All Articles