scala - массив против arrayseq - PullRequest
       1

scala - массив против arrayseq

11 голосов
/ 17 февраля 2011

это немного общий вопрос, но мне было интересно, кто-нибудь мог бы посоветовать мне, что было бы преимуществом работы с массивами по сравнению с arrayseq. Из того, что я видел, Array - это представление java Arrays в scala, и в его API-интерфейсе не так много членов, тогда как Arrayseq, кажется, содержит гораздо более богатые API-интерфейсы. спасибо за любой совет.

Ответы [ 4 ]

38 голосов
/ 17 февраля 2011

На самом деле есть четыре различных класса, из которых вы можете выбрать функциональность, похожую на изменяемый массив.

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, почему бы не добавить дополнительную гибкость в изменении длины, пока вы на нем?

8 голосов
/ 17 февраля 2011

Array является прямым представлением Java Array и использует точно такой же байт-код в JVM.

Преимущество массива в том, что это тип сбора only в JVM, который не подвергается стиранию типов. Массивы также могут напрямую хранить примитивы без упаковки, что может сделать их очень быстрыми при некоторых обстоятельствах.

Кроме того, вы получаете запутанное поведение ковариации Java. (Если вы передаете, например, Array[Int] в некоторый класс Java, его можно назначить переменной типа Array[Object], которая затем выдаст ArrayStoreException при попытке добавить что-нибудь, что не является int.)

ArraySeq в наше время используется редко, это скорее исторический артефакт из старых версий Scala, который по-разному относился к массивам. Поскольку в любом случае вам приходится иметь дело с боксом, вы почти наверняка обнаружите, что другой тип коллекции лучше соответствует вашим требованиям.

В противном случае ... Массивы имеют точно такой же API, что и ArraySeq, благодаря неявному преобразованию из Array в ArrayOps.

Если у вас нет особой потребности в уникальных свойствах массивов, постарайтесь также избегать их. См. Этот разговор около 19:30 или В этой статье , чтобы получить представление о проблемах, которые могут возникнуть в массивах.

После просмотра этого видео интересно отметить, что Scala использует Seq для varargs:)

7 голосов
/ 17 февраля 2011

На форуме scala-lang.org :

Массив [T] - Преимущества: встроенные, быстрые - Ограничения: несколько методов (толькоapply, update, length), нужно знать T во время компиляции, потому что байт-код Java представляет (char [] отличается от int [], отличается от Object [])

ArraySeq [T] (класс, ранее известный как GenericArray [T]): - Преимущества: все еще поддерживаются собственным массивом, не нужно ничего знать о T во время компиляции (новый ArraySeq [T] «просто работает», даже если ничего не происходит)известно о T), полный набор методов SeqLike, подтип Seq [T] - Ограничения: он поддерживается массивом [AnyRef], независимо от того, что такое T (если T примитивен, то элементы будут упакованы / распакованы на своихвход или выход из резервного массива)


ArraySeq [Any] намного быстрее, чем Array [Any] при обработкепримитивы.В любом коде у вас есть Array [T] , где T не <: AnyRef, вы получите более высокую производительность из ArraySeq. </p>

0 голосов
/ 17 февраля 2011

Как вы правильно заметили, ArraySeq имеет более богатый API, поскольку он получен из IndexedSeq (и т. Д.), Тогда как Array является прямым представлением массивов Java.

Отношение между обоими можно приблизительно сравнить ссоотношение ArrayList и массивов в Java.

Из-за его API я бы рекомендовал использовать ArraySeq, если нет особой причины не делать этого.Используя toArray (), вы можете конвертировать в массив в любое время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...