何时应该使用Scala的Array而不是其他集合之一?

8
这更多是关于样式和偏好的问题,但是这里有一些建议:我应该什么时候使用scala.Array?我经常使用List,偶尔用到Seq、Map之类的东西,但是从未使用过或见过实际的Array。它是否只是为了与Java兼容而存在?我是否错过了常见的用例?

我应该把这个设为社区维基吗? - pr1001
1
我不这么认为。使用Scala的数组的优缺点已经被明确定义,并且可以客观地进行争论。在我看来,这个问题是合理的。 - Daniel C. Sobral
3个回答

13
首先,让我们声明一下。Scala 2.7的Array试图同时成为Java Array和Scala Collection。它大多成功了,但在某些边缘情况下会失败。不幸的是,这些边缘情况可能发生在编写正常代码的好人身上,因此Scala 2.8正在改变这种情况。
在Scala 2.8中,有一个Java Array类型的Array。这意味着它是一个连续的内存空间,可以存储引用或原始值(因此可能具有不同的元素大小),并且可以快速随机访问。它也有糟糕的方法,可怕的toString实现,并且在同时使用泛型和原始类型时性能表现不佳(例如:def f[T](a: Array[T]) = ...; f(Array(1,2,3)))。
然后,还有一个名为GenericArray的Scala Collection,由Array支持。它始终存储装箱的原始类型,因此当混合使用原始类型和泛型时,它没有性能问题,但另一方面,它没有纯粹的原始(非泛型)原始数组的性能提升。
那么,什么时候使用什么?Array具有以下特征:
  • O(1)随机读写
  • O(n)追加/前置/插入/删除
  • 可变的
如果您不需要泛型,或者您的泛型可以表示为[T <: AnyRef],因此排除了原始类型,即AnyVal,并且这些特性对于您的代码是最佳的,则使用它。
如果您确实需要泛型,包括原始类型,并且这些特性对于您的代码是最佳的,请在Scala 2.8中使用GenericArray。此外,如果您想要一个真正的Collection,带有所有方法,您可能也想使用它,而不是依赖于隐式转换。
如果您想要不可变性或者如果您需要追加、前置、插入或删除的良好性能,请寻找其他集合。

3

当您有许多相同(或兼容)类的项目,并且您事先知道这些项目的确切数量或合理的上限,并且您对快速随机访问和可能的原地更改感兴趣时,数组是适当的选择,但设置完成后,您将永远不会在列表中的某个位置插入或删除项目。

换句话说,它是一种聚合数据结构,比Collection类型少了些花哨,开销略小,性能略优,具体取决于使用方式。

一个非常牵强的例子:您从事函数生产业务,质量测试涉及检查1000个固定输入值的性能或结果。此外,您决定不将这些值保存在文件中,而是将它们硬编码到程序中。数组是适当的选择。


3

与Java API的接口是一个例子。与Java数组不同,Scala数组是不变的,因此在这方面与列表没有任何优势。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接