这是一个普遍的问题,但我想知道是否有人可以告诉我使用数组与arrayseq有什么好处。从我所看到的Array是scala对java Arrays的表示,并且在它的api中没有太多成员,而Arrayseq似乎包含更丰富的api。谢谢你的任何建议。
答案 0 :(得分:36)
实际上有四种不同的类可供选择,以获得类似于数组的可变功能。
Array + ArrayOps
WrappedArray
ArraySeq
ArrayBuffer
Array
是一个普通的旧Java数组。它是迄今为止对基元数组进行低级访问的最佳方法。没有开销。此外,它可以像Scala集合一样,因为隐式转换为ArrayOps
,它抓取底层数组,应用适当的方法,并在适当的情况下返回一个新数组。但由于ArrayOps
并非专门用于基元,因此它很慢(与装箱/拆箱一样慢)。
WrappedArray
是一个普通的旧Java数组,但包含在所有Scala的集合中。它与ArrayOps
之间的区别在于WrappedArray
返回另一个WrappedArray
- 所以至少你没有必须重新ArrayOps
Java原始数组的开销每次操作一遍又一遍。当你使用Java进行大量的互操作并且需要传入普通的旧Java数组时,最好使用它,但是在Scala端你需要方便地操作它们。
ArraySeq
将其数据存储在普通的旧Java数组中,但它不再存储基元数组;一切都是一系列的对象。这意味着原语在路上被装箱。如果你想多次使用原语,这实际上很方便;由于您已经存储了盒装副本,因此您只需要将它们取消装箱,而不是装箱并在每次通用操作中取消装箱。
ArrayBuffer
就像一个数组,但您可以添加和删除元素。如果您要一直走到ArraySeq
,那么为什么不能在您使用时更改灵活性?
答案 1 :(得分:8)
Array
是Java Array
的直接表示,并在JVM上使用完全相同的字节码。
Array的优点是它是JVM上的 only 集合类型,不进行类型擦除,Arrays也可以直接保存基元而不需要装箱,这可以使它们在某些情况下非常快
另外,你得到了Java乱七八糟的数组协方差行为。 (如果您将例如Array[Int]
传递给某个Java类,则可以将其分配给Array[Object]
类型的变量,然后在尝试添加不是{ArrayStoreException
的任何内容时抛出int
{1}}。)
ArraySeq
现在很少使用,它更像是Scala旧版本的历史工件,它对数组的处理方式不同。无论如何你看到你必须处理拳击,你几乎肯定会发现另一种集合类型更适合你的要求。
否则......由于从Array
到ArrayOps
的隐式转换,数组与ArraySeq具有完全相同的API。
除非您特别需要数组的唯一属性,否则请尽量避免使用它们。 请参阅This Talk at around 19:30或This Article,了解阵列可能引入的问题类型。
观看该视频后,有趣的是Scala使用Seq
进行varargs:)
答案 2 :(得分:7)
数组[T] - 优点:原生,快速 - 局限性:几种方法(仅适用于, 更新,长度),需要知道T at 编译时,因为Java字节码 表示(char []与...不同 int []与Object [])不同
ArraySeq [T] (该类以前称为 as GenericArray [T]): - 好处:仍然 由本机Array支持,不需要 了解T的任何信息 编译时(新的ArraySeq [T]“只是 即使没有任何了解,也能“工作” T),全套SeqLike方法, Seq [T]的子类型 - 限制:它是 无论如何都由Array [AnyRef]支持 什么是T(如果T是原始的话,那么 元素将被装箱/取消装箱 他们进出支持的方式 阵列)
ArraySeq [Any] 比快得多 处理基元时数组[任意] 。 在任何代码中你都有 Array [T] ,其中T 不是&lt ;: AnyRef,你会变得更快 性能超出ArraySeq。
答案 3 :(得分:0)
正如您所观察到的那样,ArraySeq具有更丰富的API,因为它是从IndexedSeq(等等)派生的,而Array是Java数组的直接表示。
两者之间的关系可以粗略地与ArrayList和Java中的数组的关系进行比较。
由于它的API,我建议使用ArraySeq,除非有特殊原因不这样做。使用toArray(),您可以随时转换为数组。