scala中数组和列表的区别

Posted

技术标签:

【中文标题】scala中数组和列表的区别【英文标题】:Difference between Array and List in scala 【发布时间】:2011-02-12 08:41:21 【问题描述】:

在什么情况下我应该使用 Array(Buffer) 和 List(Buffer)。我知道的唯一区别是数组是不变的,而列表是协变的。但是性能和其他一些特性呢?

【问题讨论】:

【参考方案1】:

除了已经发布的答案,这里还有一些细节。

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)

因此,除非您需要快速随机访问、需要计数元素,或者出于某种原因需要破坏性更新,否则ListArray 更好。

【讨论】:

这些Os要考虑复制List的时间吗?我假设你正在做这样的测试,例如:list = list.drop(i)。或者,在幕后会发生什么神奇的事情吗? 这会在必要时考虑复制列表和数组。请注意,drop 之类的东西永远不需要复制未删除的列表部分。例如。 (x::xs).drop(1) 正是 xs,而不是 xs 的“副本”。 这些渐近线与 Scala 无关。 C 中相同的数据结构在常数因子下的速度将完全一样。 @Apocalisp 您是否有参考资料或您在什么条件下确定此信息? @Phil 这些是渐近的,不是测量值。它们在所有条件下都适用。【参考方案2】:

不可变结构

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 应该保持在最低限度,因为感觉就像你真的需要知道幕后发生的事情来决定你的数组是否真的会得到必需的原始类型,或者可以装箱为包装类型。

【讨论】:

另见***.com/questions/3213368/… 和***.com/questions/2481149/… 数组“等于”的定义是它们引用同一个数组【参考方案3】:

Array 是可变的,这意味着您可以更改每个索引的值,而 List(默认情况下)是不可变的,这意味着每次进行修改时都会创建一个新列表。在大多数情况下,使用不可变数据类型是一种更“实用”的风格,您可能应该尝试使用具有 yieldforeachmatch 等结构的 List。

对于性能特征,随机访问元素时 Array 更快,而在预置(添加)新元素时 List 更快。迭代它们是可比的。

【讨论】:

@leonm - apols,我以为 OP 只询问 *Buffer 类,我意识到他们也在询问“正常”类! 添加到 ArrayBuffer 通常比添加到列表(或添加元素到 ListBuffer)更快,因为列表需要创建包装对象,而 ArrayBuffer 只需要复制对象(在平均大约两次)到一个新数组。两个副本通常比创建一个对象要快,因此 ArrayBuffer append 通常优于 List prepend。 array 在iterate over 时的执行速度比 list 快得多,因为缓存

以上是关于scala中数组和列表的区别的主要内容,如果未能解决你的问题,请参考以下文章

scala集合

Spark记录-Scala集合

将 Scala 数组转换为唯一排序列表的有效方法

大数据之脚踏实地学15--Scala的数组操作

播放 Anorm 将 scala 列表插入到 postgres 文本数组列中

如何使用 Scala 从 Spark 中的列表或数组创建行