什么时候应该使用Scala的Array而不是其他集合?

时间:2009-11-24 21:09:09

标签: arrays scala coding-style scala-collections

这更像是一个风格和偏好的问题,但这里说:我什么时候应该使用scala.Array?我一直使用List,偶尔遇到Seq,Map等,但我从未使用过,也没有看过Array。是否仅适用于Java兼容性?我错过了一个常见的用例吗?

3 个答案:

答案 0 :(得分:12)

首先,我们在这里做一个免责声明。 Scala 2.7的Array同时尝试成为Java Array和Scala集合。它主要成功,但在某些角落情况下都失败了。不幸的是,这些极端情况可能发生在具有正常代码的优秀人员身上,因此Scala 2.8正在脱离这一点。

在Scala 2.8上,有Array,即Java Array。这意味着它是一个连续的内存空间,它存储引用或基元(因此,可能具有不同的元素大小),并且可以非常快速地随机访问。它也有糟糕的方法,可怕的toString实现,并且在同时使用泛型和基元时表现不佳(例如:def f[T](a: Array[T]) = ...; f(Array(1,2,3)))。

然后,有GenericArray,这是一个由Array支持的Scala Collection。它总是存储盒装基元,因此在混合基元和泛型时它没有性能问题,但另一方面,它没有纯粹原始(非泛型)基元数组的性能增益。

那么,何时使用什么? Array具有以下特征:

  • O(1)随机读写
  • O(n)追加/前置/插入/删除
  • 可变

如果您不需要泛型,或者您的泛型可以表示为[T <: AnyRef],因此排除AnyVal的基元,并且这些特征对于您的代码是最佳的,那么就去做吧。

如果您确实需要泛型,包括基元,并且这些特性对于您的代码是最佳的,请在Scala 2.8上使用GenericArray。此外,如果您想要一个真正的Collection及其所有方法,您可能也想使用它,而不是依赖于隐式转换。

如果您想要不变性,或者如果您需要良好的追加,前置,插入或删除性能,请寻找其他一些集合。

答案 1 :(得分:3)

如果您拥有相同(或兼容)类的多个项目,并且事先知道这些项目的确切数量或合理的上限,并且您对快速随机访问感兴趣,则数组是合适的并且可能就地更改项目,但在设置之后,您永远不会在列表中的某处插入或删除项目。

或者以另一种方式说明,它是一种聚合数据结构,其收集类型少于花哨和口哨,开销略小,性能稍好,具体取决于它的使用方式。

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

答案 2 :(得分:3)

与Java API的接口就是一种情况。与Java数组不同,scala数组是不变的,因此与列表相比没有任何优势。