在什么情况下我应该使用Array(Buffer)和List(Buffer)。我所知道的唯一区别是数组是非变量的,列表是协变的。但是性能和其他一些特性呢?
答案 0 :(得分:141)
Scala List
是一个不可变的递归数据结构,它是Scala中的一个基本结构,你应该(可能)使用它比Array
更多(实际上是可变 - Array
的不可变模拟为IndexedSeq
)。
如果您来自Java背景,那么明显的并行是何时使用LinkedList
而不是ArrayList
。前者通常用于只有遍历的列表(并且其大小不是预先知道的),而后者应该用于具有已知大小(或最大大小)或者已知大小的列表。 快速随机访问非常重要。
ListBuffer
提供了List
的固定时间转换,如果需要稍后进行转换,则单独使用ListBuffer
。
scala Array
应该由Java数组在JVM上实现,因此Array[Int]
可能比int[]
更高效(List[Int]
} @specialized
(除非您使用的是具有新Array
功能的最新版本的Scala,否则将封装其内容。)
但是,我认为在Scala中使用{{1}}应该保持在最低限度,因为感觉你真的需要知道幕后发生了什么来决定你的阵列是否真的会得到支持按所需的基本类型,或者可以装箱为包装类型。
答案 1 :(得分:124)
除了已经发布的答案之外,还有一些细节。
虽然Array[A]
实际上是一个Java数组,但List[A]
是一个不可变的数据结构,可以是Nil
(空列表),也可以是一对(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)
因此,除非您需要快速随机访问,需要计算元素,或者出于某种原因需要破坏性更新,List
优于Array
。
答案 2 :(得分:17)
Array是可变的,这意味着您可以更改每个索引的值,而List(默认情况下)是不可变的,这意味着每次进行修改时都会创建一个新列表。在大多数情况下,使用不可变数据类型是一种更“功能”的样式,您应该尝试使用包含yield
,foreach
,match
等结构的List。 / p>
对于性能特征,通过随机访问元素,Array更快,而在添加(添加)新元素时,List更快。迭代它们是可比的。