【发布时间】:2011-02-12 08:41:21
【问题描述】:
在什么情况下我应该使用 Array(Buffer) 和 List(Buffer)。我知道的唯一区别是数组是不变的,而列表是协变的。但是性能和其他一些特性呢?
【问题讨论】:
标签: arrays list scala scala-collections
在什么情况下我应该使用 Array(Buffer) 和 List(Buffer)。我知道的唯一区别是数组是不变的,而列表是协变的。但是性能和其他一些特性呢?
【问题讨论】:
标签: arrays list scala scala-collections
除了已经发布的答案,这里还有一些细节。
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 更好。
【讨论】:
list = list.drop(i)。或者,在幕后会发生什么神奇的事情吗?
drop 之类的东西永远不需要复制未删除的列表部分。例如。 (x::xs).drop(1) 正是 xs,而不是 xs 的“副本”。
Scala List 是一个不可变的递归数据结构,它是 Scala 中的一个基本结构,因此您应该(可能)使用它远远超过 Array(实际上是可变) > - Array 的不可变模拟是 IndexedSeq)。
如果您来自 Java 背景,那么明显的相似之处是何时使用 LinkedList 而不是 ArrayList。前者通常用于仅遍历的列表(并且其大小预先未知),而后者应用于具有已知大小(或最大大小)或快速随机访问很重要。
ListBuffer 提供到 List 的恒定时间转换,如果需要稍后进行此类转换,这就是使用 ListBuffer 的唯一理由。
scala Array 应该通过 Java 数组在 JVM 上实现,因此 Array[Int] 可能比 List[Int] 性能更高(作为 int[])(它将装箱其内容,除非您正在使用具有新的@specialized 功能的最新版本的 Scala。
但是,我认为在 Scala 中使用 Arrays 应该保持在最低限度,因为感觉就像你真的需要知道幕后发生的事情来决定你的数组是否真的会得到必需的原始类型,或者可以装箱为包装类型。
【讨论】:
Array 是可变的,这意味着您可以更改每个索引的值,而 List(默认情况下)是不可变的,这意味着每次进行修改时都会创建一个新列表。在大多数情况下,使用不可变数据类型是一种更“实用”的风格,您可能应该尝试使用具有 yield、foreach、match 等结构的 List。
对于性能特征,随机访问元素时 Array 更快,而在预置(添加)新元素时 List 更快。迭代它们是可比的。
【讨论】:
iterate over 时的执行速度比 list 快得多,因为缓存