Scala等效于java.util.ArrayList


71

我正在Scala中做一个项目,但是对于该语言来说还很新,并且具有Java背景。我看到Scala没有ArrayList,所以我想知道Scala相当于Java的ArrayList是什么,以及Java和Scala版本之间是否有重要区别。

编辑: 我不是在寻找一种特定的行为,而是在内部表示(数据存储在数组中,但是整个数组不可见,只有您使用的部分)。


可见的整个阵列与您使用的部分之间有什么区别?
Daniel C. Sobral

@Daniel,对我而言,主要区别在于ArrayList为我处理大小(即,如果我不知道它将是什么,或者知道它会发生变化,那么我不必担心分配额外的空间并保持跟踪我实际使用了多少空间)。
astay13

Answers:


113

我可以想到3个更具体的问题来解决您的问题:

  • Scala的默认集合是什么?
  • 什么Scala集合具有相似的特征ArrayList
  • 什么可以替代ArrayScala?

因此,这是这些的答案:

Scala的默认集合是什么?

Scala与JavaList接口等效Seq。还存在一个更通用的接口,这是GenSeq-主要区别在于GenSeq,根据实现的不同,a可以串行或并行处理操作。

因为Scala允许程序员Seq用作工厂,所以除非他们关心它,否则他们通常不必费心定义一个特定的实现。当他们这样做时,他们通常会选择ScalaListVector。它们都是不可变的,并且Vector具有良好的索引访问性能。另一方面,List操作得很好。

什么Scala集合具有相似的特征ArrayList

那会是scala.collection.mutable.ArrayBuffer

什么可以替代ArrayScala?

好吧,好消息是,您可以Array在Scala中使用!在Java中,Array由于与泛型一般不兼容,因此通常避免使用。它是一个协变量集合,而泛型是不变的,它是可变的-这使其协变成为一种危险,它接受泛型没有的原语,并且它的方法集非常有限。

在Scala中(ArrayArrayJava相同)是不变的,这使大多数问题都消失了。Scala接受AnyVal(等效于基本体)作为其“泛型”的类型,即使它会进行自动装箱。并通过“丰富我的图书馆”模式,所有Seq方法可用来Array

因此,如果您想要更强大的功能Array,请使用Array

缩小和增长的集合呢?

所有集合可用的默认方法都会产生集合。例如,如果我这样做:

val ys = xs filter (x => x % 2 == 0)

然后ys将是一个集合,而xs该命令仍将与之前相同。这是真实的,不管是什么xs是:ArrayList,等。

自然,这是有成本的-毕竟,您正在生产一个新的系列。Scala的不可变集合具有持久性,因此在处理此成本方面要好得多,但这取决于要执行的操作。

没有任何集合可以做很多事情filter,但是List在通过添加元素或移除头部(实际上是堆栈的基本操作)来生成新集合方面,它具有出色的性能。Vector在一系列操作上都有不错的表现,但是只有在集合不小的情况下才需要付费。例如,对于多达一百个元素的集合,总成本可能会超过收益。

因此,您实际上可以在中添加或删除元素Array,Scala会为您生成一个 Array副本,但是您需要为此支付完整副本的费用。

Scala可变集合添加了其他一些方法。特别是,可以增加或减小大小的集合-无需产生新的集合-即可实现GrowableShrinkable特性。但是,它们不能保证这些操作的良好性能,但是会为您指出要检出的集合。


13
是一个在线测试,表明尽管进行了必要的重新分配,但测试ArrayList速度比快3倍LinkedList。我不得不减少N使其在线运行。随着N = 50000000我自己的机器上,ArrayList大约是10倍的速度比LinkedList。您在计算机上得到什么结果?如果LinkedList速度更快,我会感到非常惊讶,因为它每次插入(时间)需要更多分配,并且每个元素都需要一个额外的Node对象(空间)。
fredoverflow

7
@ DanielC.Sobral:是一个后续的在线测试,显示ArrayListLinkedList中间插入的速度快12倍。 LinkedList在靠近开始处插入时显示更快。
Mooing Duck 2013年

6
@ DanielC.Sobral:ArrayList每次重新分配大小时,其大小都会增加一倍,这意味着最多最多可以进行元素复制的两倍,换句话说,每个元素平均要复制两次。就是说,无论您增加阵列多少。作为回报,您将获得更有效的数据结构,具有更好的局部性和缓存特性。链接列表几乎永远不会更快。如果你从来没有需要查找的元素,你永远需要遍历数据结构,那么一个链表可能会更快。除此以外?号
2013年

3
@ DanielC.Sobral:在这种情况下,ArrayList平时还是比较快的,因为它是较少的分配,间接更少,更好的内存位置。请记住,插入列表的中间位置需要您反复查找中间位置。对于链表,这慢得多。经验法则是:“对于某些事情,显然ArrayList更快。对于其他事情,令人惊讶的ArrayList是更快”。:)
杰夫

1
并非总是如此,但是CPU和内存性能之间的差距变得越来越大。随机内存访问慢得令人痛苦,和链表的所有随机访问。ArrayList(或任何其他动态数组数据结构)几乎没有随机访问。从硬件的角度来看,这几乎是一个巨大的优势,无论您对数据结构执行哪种操作
jalf


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.