The immutable.Queue standard in Scala can be adapted to work this way for amortized complexity. Note, however, that the peek operation will return a new queue, or, in the opposite case, consecutive calls to peek could very well be made in O (n).
You can either extend Queue or create a new class that adapts it. Here is the version expanding it:
import scala.collection._ import generic._ import immutable.Queue import mutable.{ Builder, ListBuffer } class MyQueue[+A] protected(in0: List[A], out0: List[A]) extends scala.collection.immutable.Queue[A](in0, out0) with GenericTraversableTemplate[A, MyQueue] with LinearSeqLike[A, MyQueue[A]] { override def companion: GenericCompanion[MyQueue] = MyQueue def peek: (A, MyQueue[A]) = out match { case Nil if !in.isEmpty => val rev = in.reverse ; (rev.head, new MyQueue(Nil, rev)) case x :: xs => (x, this) case _ => throw new NoSuchElementException("dequeue on empty queue") } override def tail: MyQueue[A] = if (out.nonEmpty) new MyQueue(in, out.tail) else if (in.nonEmpty) new MyQueue(Nil, in.reverse.tail) else throw new NoSuchElementException("tail on empty queue") override def enqueue[B >: A](elem: B) = new MyQueue(elem :: in, out) // This ought to be override, but scalac doesn't think so! def enqueue[B >: A](iter: Iterable[B]) = new MyQueue(iter.toList.reverse ::: in, out) override def dequeue: (A, MyQueue[A]) = out match { case Nil if !in.isEmpty => val rev = in.reverse ; (rev.head, new MyQueue(Nil, rev.tail)) case x :: xs => (x, new MyQueue(in, xs)) case _ => throw new NoSuchElementException("dequeue on empty queue") } override def toString() = mkString("MyQueue(", ", ", ")") } object MyQueue extends SeqFactory[MyQueue] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, MyQueue[A]] = new GenericCanBuildFrom[A] def newBuilder[A]: Builder[A, MyQueue[A]] = new ListBuffer[A] mapResult (x => new MyQueue[A](Nil, x.toList)) override def empty[A]: MyQueue[A] = EmptyQueue.asInstanceOf[MyQueue[A]] override def apply[A](xs: A*): MyQueue[A] = new MyQueue[A](Nil, xs.toList) private object EmptyQueue extends MyQueue[Nothing](Nil, Nil) { } }
Daniel C. Sobral
source share