7

只是在这里搞乱,使用循环缓冲区。这是一个明智的实现,还是有更快/更可靠的方法给这只猫剥皮?

class CircularBuffer[T](size: Int)(implicit mf: Manifest[T]) {

    private val arr = new scala.collection.mutable.ArrayBuffer[T]()

    private var cursor = 0

    val monitor = new ReentrantReadWriteLock()

    def push(value: T) {
      monitor.writeLock().lock()
      try {
        arr(cursor) = value
        cursor += 1
        cursor %= size
      } finally {
        monitor.writeLock().unlock()
      }
    }

    def getAll: Array[T] = {
      monitor.readLock().lock()
      try {
        val copy = new Array[T](size)
        arr.copyToArray(copy)
        copy
      } finally {
        monitor.readLock().unlock()
      }
    }
  }
4

1 回答 1

5

创建

对现有 scala 集合类和 appender 函数的类型声明比“滚动你自己的”更容易实现。正如评论中所指出的,这个实现可能不会像“真正的”循环缓冲区那样高效,但它只需很少的编码就可以完成工作:

import scala.collection.immutable

type CircularBuffer[T] = immutable.Vector[T]

def emptyCircularBuffer[T] : CircularBuffer[T] = immutable.Vector.empty[T]

def addToCircularBuffer[T](maxSize : Int)(buffer : CircularBuffer[T], item : T) : CircularBuffer[T]  =
  (buffer :+ item) takeRight maxSize

这意味着您的“CircularBuffer”实际上是一个 Vector,您现在可以免费获得所有相应的 Vector 方法(filter、map、flatMap 等):

var intCircularBuffer = emptyCircularBuffer[Int]

//Vector(41)
intCircularBuffer = addToCircularBuffer(2)(intCircularBuffer, 41)

//Vector(41, 42)
intCircularBuffer = addToCircularBuffer(2)(intCircularBuffer, 42)

//Vector(42, 43)
intCircularBuffer = addToCircularBuffer(2)(intCircularBuffer, 43)

//Vector(42)
val evens : CircularBuffer[Int] = intCircularBuffer filter ( _ % 2 == 0)

索引

您可以类似地添加一个用于循环索引的函数:

def circularIndex[T](buffer : CircularBuffer[T])(index : Int) : T = 
  buffer(index % buffer.size)
于 2016-01-15T18:57:05.093 回答