在阅读Programming in Scala, 3rd Edition
时说
Class List确实提供了一个“追加”操作,它的写法是:+但是这 很少使用该操作,因为追加到 list随列表的大小线性增长,而前面加上 ::需要固定的时间。
如果您想通过添加元素来有效地构建列表,则可以 给它们添加前缀,完成后调用反向。
我试图理解,Scala惯用的方式是什么?与ListBuffer相比,调用List.reverse是否可以接受两次且效率更高(因为ListBuffer可变)?
// Scala Recommended way - but reverse twice?
val alist = List("A", "B")
// cons is O(1)
// This will print (A, B, C)
println(("C" :: alist.reverse).reverse)
// Scala also Recommended: Use ListBuffer
val alb = ListBuffer("A", "B")
alb.append("C")
val clist2 = alb.toList
// This will print (A, B, C)
println(clist2)
// DO NOT do this, its O(n)
val clist3 = alist :+ "C"
// This will print (A, B, C)
println(clist3)
P.S:我在这里不是指代码优化。通常建议使用哪一个,而不会收到 WTH 表达式。
答案 0 :(得分:0)
另一种实现方式可以是Difference Lists(也可以使用基于Prolog的解释-Understanding Difference Lists)。
这就是我在Scala中实现DList
的方式:
abstract class DiffList[A](calculate: List[A] => List[A]) {
def prepend(s: List[A]): DiffList[A]
def append(s: List[A]): DiffList[A]
def result: List[A]
}
final class DiffListImpl[A](listFunc: List[A] => List[A])
extends DiffList[A](listFunc) {
def prepend(s: List[A]): DiffListImpl[A] =
new DiffListImpl[A](listFunc andThen (s ++ _))
def append(s: List[A]): DiffListImpl[A] =
new DiffListImpl[A](listFunc andThen (_ ++ s))
def result: List[A] = listFunc(Nil)
}
并使用它:
val l1 = List(1, 2)
val l2 = List(6, 7)
val l3 = List(3, 4, 5)
val dl = new DiffListImpl[Int](Nil)
val result = dl.prepend(l1).prepend(l2).append(l3).result
Result: List(6, 7, 1, 2, 3, 4, 5)