I'm curious if Scala has some gem hidden in its collection classes that I can use. Basically I'm looking for something like a FIFO queue, but that has an upper-limit on its size such that when the limit is hit, the oldest (first) element is removed from the queue. I've implemented this myself in Java in the past, but I'd rather use something standard if possible.
An often preferable alternative to subclassing is the (unfortunately named) "pimp my library" pattern. You can use it to add an enqueueFinite
method to Queue
, like so:
import scala.collection.immutable.Queue
class FiniteQueue[A](q: Queue[A]) {
def enqueueFinite[B >: A](elem: B, maxSize: Int): Queue[B] = {
var ret = q.enqueue(elem)
while (ret.size > maxSize) { ret = ret.dequeue._2 }
ret
}
}
implicit def queue2finitequeue[A](q: Queue[A]) = new FiniteQueue[A](q)
Whenever queue2finitequeue
is in scope, you can treat Queue
objects as though they have the enqueueFinite
method:
val maxSize = 3
val q1 = Queue(1, 2, 3)
val q2 = q1.enqueueFinite(5, maxSize)
val q3 = q2.map(_+1)
val q4 = q3.enqueueFinite(7, maxSize)
The advantage of this approach over subclassing is that enqueueFinite
is available to all Queue
s, including those that are constructed via operations like enqueue
, map
, ++
, etc.
Update: As Dylan says in the comments, enqueueFinite
needs also to take a parameter for the maximum queue size, and drop elements as necessary. I updated the code.