Answers:
斯卡拉List
是不可变的递归数据结构,它是Scala这样的基本结构,你应该(可能)使用它远远超过一个是Array
(这实际上是可变的 -的不可变模拟的Array
是IndexedSeq
)。
如果您来自Java背景,那么显而易见的并行是何时使用LinkedList
over ArrayList
。前者通常用于仅遍历过的列表(其大小事先未知),而后者应用于具有已知大小(或最大大小)或快速随机访问很重要的列表。
ListBuffer
提供了对a的恒定时间转换,如果需要进行后期转换List
,则仅使用ListBuffer
该转换的理由。
一个scala Array
应该通过Java数组在JVM上实现,因此Array[Int]
可能比的性能更高(作为int[]
)List[Int]
(将装箱其内容,除非您使用的是具有新@specialized
功能的最新版本的Scala ) 。
但是,我认为Array
应尽量减少在Scala中使用s,因为感觉就像您真的需要知道幕后发生的事情一样,才能确定您的数组是否真正由所需的原始类型支持,或者被包装为包装类型。
除了已经发布的答案之外,这里还有一些细节。
虽然Array[A]
从字面上看是Java数组,但是a List[A]
是一个不变的数据结构,该结构要么是Nil
(空列表),要么是由pair组成(A, List[A])
。
性能差异
Array List
Access the ith element θ(1) θ(i)
Delete the ith element θ(n) θ(i)
Insert an element at i θ(n) θ(i)
Reverse θ(n) θ(n)
Concatenate (length m,n) θ(n+m) θ(n)
Count the elements θ(1) θ(n)
记忆差异
Array List
Get the first i elements θ(i) θ(i)
Drop the first i elements θ(n-i) θ(1)
Insert an element at i θ(n) θ(i)
Reverse θ(n) θ(n)
Concatenate (length m,n) θ(n+m) θ(n)
因此,除非您需要快速随机访问,需要对元素进行计数或出于某种原因需要破坏性更新,否则a List
优于an Array
。
drop
从不需要复制列表中未被删除的部分之类的事情。例如(x::xs).drop(1)
,完全是xs
,而不是的“副本” xs
。
数组是可变的,这意味着您可以更改每个索引的值,而列表(默认情况下)是不可变的,这意味着每次您进行修改时都会创建一个新列表。在大多数情况下,它是一个更“实用”的风格与不可改变的数据类型的工作,你或许应该尝试使用列表中包含结构yield
,foreach
,match
等等。
对于性能特征,使用数组随机访问元素会更快,而在添加(添加)新元素时,列表会更快。遍历它们是可比较的。
iterate over
由于高速缓存,数组的执行速度比列表快得多