Scala-array vs arrayseq

Это немного общий вопрос, но мне было интересно, может ли кто-нибудь посоветовать мне, каковы будут преимущества работы с массивами против arrayseq. Из того, что я видел, Array-это представление Scala массивов java, и в его api не слишком много членов, тогда как Arrayseq, похоже, содержит гораздо более богатый api. спасибо за любой совет.

4 ответов


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

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


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

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

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

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

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

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

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


из scala-lang.org форум:

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

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


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


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

отношение между обоими можно грубо сравнить с отношением ArrayList и массивов в Java.

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