如果采用函数方法,这是最有效的方法吗?
@tailrec
def readLine(in: SomeTypeOfBuffer, a: Array[Byte]): Array[Byte] = {
val char = in.readByte()
char match{
case 'n' => a
case other => readLine(in, a :+ other)
}
}
由于每个递归调用都会生成一个新的数组,因此必须对内存进行另一次调用,为另一个数组分配空间,并从内存中释放前一个数组。
这只是函数式编程的价格吗?
(我对scala和函数还比较陌生,所以如果我出了可怕的问题,请不要把我钉在十字架上(
正如@DeFuncT所说,最好使用(不可变(列表,因为它在构建时不会复制数据。我会教你怎么做。
我还将应用@QuickSilver的建议。
def readLine(in: SomeTypeOfBuffer): List[Byte] = {
val NewLine: Byte = 'n'.toByte
@annotation.tailrec
def loop(acc: List[Byte]): List[Byte]
in.readByte() match {
case NewLine => acc.reverse
case char => loop(other :: acc)
}
loop(acc = List.empty)
}
附言:在常见的Scala中,您永远不会看到数组。也许是新的ArraySeq或Vector
普通数组通常只用于性能原因,并且通常包含在单个方法的范围内。
使用内部可变性来提高效率并提供安全的不可变API:没有错
@tailrec
private def readLineInner(in: DataInputStream, a: ArrayBuffer[Byte]): Array[Byte] = {
val char = in.readByte()
char match{
case 'n' => a.toArray
case other => {
a.addOne(other)
readLineInner(in, a )
}
}
}
def readLine(in: DataInputStream): Array[Byte] =
readLineInner(in, new ArrayBuffer[Byte]())
在您的情况下最好使用List
,因为List
内部基本上是一个链表,而链表中的前缀是O(1(
编辑:更新为准备