Разница между Seq и списком в Scala

Я видел во многих примерах, что иногда используется Seq, а в других случаях List...

Есть ли какая-то разница, отличная от прежней, которая является типом Scala и списком, исходящим из Java?

Ответ 1

В терминах Java Scala Seq будет Java List, а Scala List будет Java LinkedList.

Обратите внимание, что Seq - это trait, что эквивалентно Java interface, но с эквивалентом методов защиты вверх и вниз. Scala List - абстрактный класс, который расширяется Nil и ::, которые являются конкретными реализациями List.

Итак, где Java List является interface, Scala List является реализацией.

Кроме того, Scala List является неизменным, что не относится к LinkedList. Фактически, Java не имеет эквивалента неизменяемым коллекциям (только для чтения только гарантирует, что новый объект не может быть изменен, но вы все равно можете изменить старый и, следовательно, "только для чтения" ).

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

Seq - хорошее обобщение для последовательностей, поэтому, если вы программируете на интерфейсы, вы должны использовать это. Обратите внимание, что на самом деле их три: collection.Seq, collection.mutable.Seq и collection.immutable.Seq, а последний - это "по умолчанию", импортированный в область видимости.

Там также GenSeq и ParSeq. Последние методы выполняются параллельно, где это возможно, причем первое является родительским для Seq и ParSeq обоих, являясь подходящим обобщением, когда parallelism кода не имеет значения. Они оба относительно недавно введены, поэтому люди пока не используют их много.

Ответ 2

В Scala список наследуется от Seq, но реализует Product; вот правильное определение List:

sealed abstract class List[+A] extends AbstractSeq[A] with Product with ...

[Примечание: фактическое определение немного сложнее, чтобы вписаться и использовать Scala очень мощная структура коллекции.]

Ответ 3

A Seq является Iterable, который имеет определенный порядок элементов. Последовательности предоставляют метод apply() для индексирования в диапазоне от 0 до длины последовательности. Seq имеет много подклассов, включая Queue, Range, List, Stack и LinkedList.

A List - это Seq, который реализуется как непреложный связанный список. Он лучше всего используется в случаях с шаблонами доступа с последним входом (LIFO).

Ответ 4

Seq - это признак, реализуемый List.

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

scala> def sumUp(s: Seq[Int]): Int = { s.sum }
sumUp: (s: Seq[Int])Int

scala> sumUp(List(1,2,3))
res41: Int = 6

scala> sumUp(Vector(1,2,3))
res42: Int = 6

scala> sumUp(Seq(1,2,3))
res44: Int = 6

Обратите внимание, что

scala> val a = Seq(1,2,3)
a: Seq[Int] = List(1, 2, 3)

Это всего лишь короткая рука для:

scala> val a: Seq[Int] = List(1,2,3)
a: Seq[Int] = List(1, 2, 3)

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