First of all, just grant that I do in fact want the functionality of a Queue<T>
-- FIFO, generally only need Enqueue
/Dequeue
, etc. -- and so I'd prefer an answer other than "What you really want is a List<T>
" (I know about RemoveAt
).
For example, say I have a Queue<DataPoint> dataToProcess
of data points that need to be processed in the order in which they arrived. Then periodically it would make sense to have some code like this:
while (dataToProcess.Count > 0) {
DataPoint pointToProcess = dataToProcess.Dequeue();
ProcessDataPoint(pointToProcess);
}
But then suppose, for whatever reason, it's discovered that a particular data point which has been added to the queue should not be processed. Then it would be ideal if there were a method analogous to:
dataToProcess.Remove(badPoint);
I understand that there's really no feasible way to have a Remove
method that does not involve some form of enumeration; however, since a Queue<T>
doesn't really let you just walk in and remove some item randomly, the only solution I could figure out was this:
bool Remove(T item) {
bool itemFound = false;
// set up a temporary queue to take items out
// one by one
Queue<T> receivingQueue = new Queue<T>();
// move all non-matching items out into the
// temporary queue
while (this.Count > 0) {
T next = this.Dequeue();
if (next.Equals(item)) {
itemFound = true;
} else {
receivingQueue.Enqueue(next);
}
}
// return the items back into the original
// queue
while (receivingQueue.Count > 0) {
this.Enqueue(receivingQueue.Dequeue());
}
return itemFound;
}
Is this ridiculous? It certainly looks bad, but I can't really see a better way, other than writing a custom class. And even then, the best way I could think to implement a Remove
method would be to use a LinkedList<T>
internally.
Queue remove() method in Java The remove() method of Queue Interface returns and removes the element at the front of the container. It deletes the head of the container. The method throws an NoSuchElementException when the Queue is empty.
It's better to use ArrayDeque instead of LinkedList when implementing Stack and Queue in Java. ArrayDeque is likely to be faster than Stack interface (while Stack is thread-safe) when used as a stack, and faster than LinkedList when used as a queue.
You could use the method: remove(Object o) Removes the first occurrence of the specified element from this list, if it is present. If this list does not contain the element, it is unchanged.
I think switching over to a new custom class that had a LinkedList internally would only take you a few minutes and would be much more performant than what you have now.
public class SpecialQueue<T>
{
LinkedList<T> list = new LinkedList<T>();
public void Enqueue(T t)
{
list.AddLast(t);
}
public T Dequeue()
{
var result = list.First.Value;
list.RemoveFirst();
return result;
}
public T Peek()
{
return list.First.Value;
}
public bool Remove(T t)
{
return list.Remove(t);
}
public int Count { get { return list.Count; } }
}
An alternative could be to just leave the items in the queue, and ignore them when you are reading from it. Something like:
T DequeueFiltered(HashSet<T> ignored) {
T item;
while (ignored.Contains(item = Dequeue())) {
ignored.Remove(item);
}
return item;
}
I am a beginner however I managed to solve the same (or a very similar) issue recently. I hope it helps.
Here is our queue:
Queue<T> dataToProcess = new Queue<T>();
What if we put a copy of all enqueued items into a hashset (e.g.:
HashSet<T> pointsToProcess = new HashSet<T>();
so when enqueueing the elements we also add the same data to the hashset.
and When it turns out we don't need an element, we remove it from that hashset
pointsToProcess.Remove(element);
so when we have to 'use' the next element of the queue,
we examine whether we really need to deal with it (if it's member of the hashset) otherwise it has to be ignored and we can get rid of it,
while (dataToProcess.Count > 0) {
if pointsToProcess.Contains(dataToProcess.Peek())
{
// processing data
}
else
{
// error message and
dataToProcess.Dequeue();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With