【问题标题】:When should I use Scala's Array instead of one of the other collections?我什么时候应该使用 Scala 的 Array 而不是其他集合之一?
【发布时间】:2010-12-20 01:26:01
【问题描述】:

这更多是风格和偏好的问题,但这里有:我什么时候应该使用 scala.Array?我一直在使用 List,偶尔会遇到 Seq、Map 等,但我从来没有在野外使用过,也没有见过 Array。它只是为了Java兼容性吗?我错过了一个常见的用例吗?

【问题讨论】:

  • 我应该把它变成一个社区维基吗?
  • 我不这么认为。使用 Scala 的 Array 的优缺点非常明确,可以客观地讨论。这个问题是正确的,恕我直言。

标签: arrays scala coding-style scala-collections


【解决方案1】:

首先,让我们在这里做一个免责声明。 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 集合。它始终存储盒装的基元,因此在混合基元和泛型时不会出现性能问题,但另一方面,它没有纯基元(非泛型)基元数组的性能提升。

那么,什么时候用什么? Array 具有以下特点:

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

如果您不需要泛型,或者您的泛型可以声明为[T <: AnyRef],从而排除原语,即AnyVal,并且这些特性对您的代码来说是最佳的,那么就去吧。

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

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

【讨论】:

    【解决方案2】:

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

    或者换一种说法,它是一种聚合数据结构,比 Collection 类型花里胡哨的少,开销略少,性能略好,具体取决于它的使用方式。

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-11
        • 2011-08-01
        • 2016-08-09
        • 2011-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-14
        相关资源
        最近更新 更多