scala中Array和List之间的区别

Jer*_*iho 129 arrays scala list scala-collections

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

oxb*_*kes 147

不可变结构

斯卡拉List是不可变的递归数据结构,它是Scala这样的基本结构,你应该(可能)使用它比更是Array(实际上是可变的 -的不可变模拟ArrayIndexedSeq).

如果你是从Java背景的,则明显是平行时使用LinkedListArrayList.前者通常用于仅被遍历的列表(并且其大小不是预先知道的),而后者应该用于具有已知大小(或最大大小)或快速随机访问很重要的列表.

可变结构

ListBuffer如果需要这样的后续转换,则提供恒定时间转换,List这是单独使用的原因ListBuffer.

Array应该通过Java数组在JVM上实现scala ,因此Array[Int]可能int[]比a List[Int](它将包含其内容)更高效(除非您使用具有新@specialized功能的Scala的最新版本) .

但是,我认为Array在Scala中使用s应该保持在最低限度,因为感觉你真的需要知道底层发生了什么,以决定你的数组是否真的会被所需的基本类型支持,或者可能被装箱作为包装类型.


Apo*_*isp 128

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

虽然a Array[A]实际上是一个Java数组,但是a 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)
Run Code Online (Sandbox Code Playgroud)

记忆差异

                          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)
Run Code Online (Sandbox Code Playgroud)

因此,除非您需要快速随机访问,需要计算元素,或者出于某种原因需要破坏性更新,否则List优于a Array.

  • 这些渐近线与Scala无关.C中相同的数据结构与常数因子一样快. (6认同)
  • 这会在必要时考虑复制列表和数组.请注意,像`drop`这样的东西永远不需要复制未删除的列表部分.例如`(x :: xs).drop(1)`正好是`xs`,而不是`xs`的"副本". (2认同)

leo*_*onm 17

Array是可变的,这意味着您可以更改每个索引的值,而List(默认情况下)是不可变的,这意味着每次进行修改时都会创建一个新列表.在大多数情况下,它是一个更"实用"的风格与不可改变的数据类型工作,你或许应该尝试使用列表中包含结构yield,foreach,match等等.

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

  • 附加到 ArrayBuffer 通常比附加到列表(或将元素添加到 ListBuffer)更快,因为列表需要创建包装对象,而 ArrayBuffer 只需要将对象(平均大约两次)复制到新数组. 两个副本通常比创建一个对象更快,因此 ArrayBuffer append 通常优于 List prepend。 (2认同)