2009-11-24 2 views
8

Это скорее вопрос стиля и предпочтения, но здесь идет: когда следует использовать scala.Array? Я использую List все время и время от времени сталкиваюсь с Seq, Map и т. П., Но я никогда не использовал и не видел Array в дикой природе. Это просто совместимость с Java? Я пропустил общий прецедент?Когда следует использовать Scala's Array вместо одной из других коллекций?

+0

Должен ли я сделать это сообщество wiki? – pr1001

+1

Я так не думаю. Плюсы и минусы использования Scala's Array довольно хорошо определены и могут быть аргументированы объективно. Вопрос звучит, ИМХО. –

ответ

12

Прежде всего, давайте сделаем отказ от ответственности здесь. Scala 2.7's 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, который представляет собой коллекцию Scala под номером Array. Он всегда хранит примитивы в коробке, поэтому он не имеет проблем с производительностью при смешивании примитивов и дженериков, но, с другой стороны, он не имеет прироста производительности чисто примитивного (не общего) примитивного массива.

Итак, когда использовать что? Array имеет следующие характеристики:

  • O (1) случайное чтения и записи
  • O (п) Append/перед именем/вставка/удаление
  • изменяемые

Если вы не нужны дженерики, или ваши дженерики могут быть указаны как [T <: AnyRef], таким образом исключая примитивы, которые являются AnyVal, и эти характеристики являются оптимальными для вашего кода, а затем идут на это.

Если вам нужны дженерики, в том числе примитивы, и эти характеристики оптимальны для вашего кода, используйте GenericArray на Scala 2.8. Кроме того, если вы хотите создать настоящую коллекцию со всеми ее методами, вы можете использовать ее также, а не в зависимости от неявных преобразований.

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

+0

Спасибо, Даниэль, это отличный ответ. – pr1001

3

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

Или заявлено иначе, это совокупная структура данных с меньшим количеством звонков и свистов, чем типы коллекции, с немного меньшими накладными расходами и немного лучшей производительностью в зависимости от того, как она используется.

Очень надуманный пример: вы занимаетесь производством функций, а тестирование качества для этих функций включает проверку их производительности или результатов для набора из 1000 фиксированных входных значений. Более того, вы решили не сохранять эти значения в файле, а скорее жестко закодировать их в своей программе. Массив будет подходящим.

3

Взаимодействие с API Java - это один случай. Кроме того, в отличие от массивов Java, scala-массивы являются инвариантными и, следовательно, не имеют никакого преимущества по сравнению с списками из-за этого.

Смежные вопросы