![](/img/trans.png)
[英]Scala call length() on very long string throws exception: Maximum String literal length exceeded
[英]Maximum Length for scala queue
我很好奇 Scala 是否在我可以使用的集合類中隱藏了一些 gem。 基本上我正在尋找類似 FIFO 隊列的東西,但是它的大小有上限,這樣當達到限制時,最舊的(第一個)元素將從隊列中刪除。 過去我自己在 Java 中實現了這一點,但如果可能的話,我寧願使用標准的東西。
子類化的一個通常更可取的替代方法是(不幸命名的)“ pimp my library ”模式。 您可以使用它向Queue
添加一個enqueueFinite
方法,如下所示:
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)
只要queue2finitequeue
在范圍內,您就可以將Queue
對象視為具有enqueueFinite
方法:
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)
與子類化相比,這種方法的優勢在於enqueueFinite
可用於所有Queue
,包括通過enqueue
、 map
、 ++
等操作構造的那些。
更新:正如 Dylan 在評論中所說, enqueueFinite
還需要為最大隊列大小取一個參數,並根據需要刪除元素。 我更新了代碼。
為什么不只是將 FIFO 隊列子類化? 像這樣的東西應該可以工作:(偽代碼如下......)
class Limited(limit:Int) extends FIFO {
override def enqueue() = {
if (size >= limit) {
//remove oldest element
}
super.enqueue()
}
}
這是一個不可變的解決方案:
class FixedSizeFifo[T](val limit: Int)
( private val out: List[T], private val in: List[T] )
extends Traversable[T] {
override def size = in.size + out.size
def :+( t: T ) = {
val (nextOut,nextIn) = if (size == limit) {
if( out.nonEmpty) {
( out.tail, t::in )
} else {
( in.reverse.tail, List(t) )
}
} else ( out, t::in )
new FixedSizeFifo( limit )( nextOut, nextIn )
}
private lazy val deq = {
if( out.isEmpty ) {
val revIn = in.reverse
( revIn.head, new FixedSizeFifo( limit )( revIn.tail, List() ) )
} else {
( out.head, new FixedSizeFifo( limit )( out.tail, in ) )
}
}
override lazy val head = deq._1
override lazy val tail = deq._2
def foreach[U]( f: T => U ) = ( out ::: in.reverse ) foreach f
}
object FixedSizeFifo {
def apply[T]( limit: Int ) = new FixedSizeFifo[T]( limit )(List(),List())
}
一個例子:
val fifo = FixedSizeFifo[Int](3) :+ 1 :+ 2 :+ 3 :+ 4 :+ 5 :+ 6
println( fifo ) //prints: FixedSizeFifo(4, 5, 6)
println( fifo.head ) //prints: 4
println( fifo.tail :+ 7 :+8 ) //prints: FixedSizeFifo(6, 7, 8)
這是我在擴展 Scala 的標准mutable.Queue類時采用的方法。
class LimitedQueue[A](maxSize: Int) extends mutable.Queue[A] {
override def +=(elem: A): this.type = {
if (length >= maxSize) dequeue()
appendElem(elem);
this
}
}
和簡單的用例
var q2 = new LimitedQueue[Int](2)
q2 += 1
q2 += 2
q2 += 3
q2 += 4
q2 += 5
q2.foreach { n =>
println(n)
}
您將在控制台中只得到4
和5
,因為舊元素事先已出列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.