Diferença entre uma Seq e uma lista em Scala


299

Já vi em muitos exemplos que algumas vezes uma Seq está sendo usada, enquanto outras é a Lista ...

Existe alguma diferença, além de o primeiro ser do tipo Scala e a lista vinda do Java?

Respostas:


408

Em termos de Java, Scala Seqseria Java Liste Scala Listseria Java LinkedList.

Observe que Seqé a trait, que é equivalente ao Java interface, mas com o equivalente aos métodos defensores promissores. Scala's Listé uma classe abstrata que é estendida por Nile ::, quais são as implementações concretas de List.

Então, onde Java Listé um interface, Scala Listé uma implementação.

Além disso, o Scala's Listé imutável, o que não é o caso LinkedList. De fato, Java não tem equivalente a coleções imutáveis ​​(a coisa somente leitura garante que o novo objeto não possa ser alterado, mas você ainda pode alterar a antiga e, portanto, a "somente leitura").

O Scala's Listé altamente otimizado por compilador e bibliotecas, e é um tipo de dados fundamental em programação funcional. No entanto, possui limitações e é inadequado para programação paralela. Hoje em dia, Vectoré uma escolha melhor do que List, mas o hábito é difícil de quebrar.

Seqé uma boa generalização para sequências; portanto, se você programa para interfaces, deve usá-lo. Note-se que na verdade existem três deles: collection.Seq, collection.mutable.Seqe collection.immutable.Seq, e é este último que é o "default" importados para escopo.

Há também GenSeqe ParSeq. Os últimos métodos são executados em paralelo, sempre que possível, enquanto o primeiro é pai de ambos Seqe ParSeq, sendo uma generalização adequada para quando o paralelismo de um código não importa. Ambos são introduzidos relativamente recentemente, para que as pessoas ainda não os usem muito.


3
RE "Java não tem equivalente a coleções imutáveis" , embora Stringnão seja uma coleção, é um exemplo de classes imutáveis ​​familiares aos programadores Java.
precisa saber é o seguinte

15
@huynhjl Isso não vem ao caso. Eu estava traçando paralelos entre o que existe em Java e o que existe em Scala, e simplesmente não há nenhum conceito de coleções mutáveis ​​/ imutáveis ​​em Java.
Daniel C. Sobral

2
Java realmente tem o equivalente a coleções imutáveis. Não é tão "bem anunciado", mas está lá e quando você usa genéricos fortemente, é provável que você acerte alguns UnsupportedOperationExceptionpor causa disso. Para criar uma lista imutável em Java, use o Collections.unmodifiableList () e, da mesma forma, existem outros métodos para Sets, Mapas etc. docs.oracle.com/javase/6/docs/api/java/util/…
jbx

27
@jbx Não é verdade. Se você usar esses métodos, obterá um objeto que lançará exceções nos métodos que o modificam, mas não um objeto imutável . Se o objeto original for modificado após a criação do objeto não modificável, o objeto não modificável refletirá isso. Então, inalterável, sim, imutável, não.
Daniel C. Sobral

3
@jbx O método de recebimento não pode manter uma referência à coleção que recebeu e assumir que nunca mudará, e não há nenhum tipo na biblioteca Java padrão que garanta isso - isso é imutabilidade. Assim, por exemplo, esse método de recebimento não pode garantir a segurança do encadeamento. E isso nem sequer toca nas características persistentes ativadas pela imutabilidade. Sem tudo isso, não pode ser chamado de "equivalente".
22813 Daniel C. Sobral

81

Uma Seq é um Iterable que possui uma ordem definida de elementos. As seqüências fornecem um método apply()para indexação, variando de 0 até o comprimento da sequência. Seq possui muitas subclasses, incluindo Fila, Intervalo, Lista, Pilha e LinkedList.

Uma lista é uma Seq implementada como uma lista vinculada imutável. É melhor usado em casos com padrões de acesso LIFO (último a entrar, primeiro a sair).

Aqui está a hierarquia completa da classe de coleção nas Perguntas frequentes do Scala :

insira a descrição da imagem aqui


2
Onde Array (e ArrayBuffer)? Não é o tipo de Iterable
Peter Krauss

23

Seq é uma característica que List implementa.

Se você definir seu contêiner como Seq, poderá usar qualquer contêiner que implemente Seqcaracterística.

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

Observe que

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

É apenas uma mão curta para:

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

se o tipo de contêiner não for especificado, a estrutura de dados subjacente será padronizada como List.


18

No Scala, uma Lista herda da Seq, mas implementa Produto ; Aqui está a definição adequada de Lista :

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

[Nota: a definição real é um pouco mais complexa, a fim de se encaixar e usar a estrutura de coleta muito poderosa do Scala.]


0

Como @ daniel-c-sobral disse, List estende a característica Seq e é uma classe abstrata implementada por scala.collection.immutable.$colon$colon(ou ::para abreviar), mas tecnicamente à parte, lembre-se de que a maioria das listas e seqs que usamos são inicializadas na forma de Seq(1, 2, 3)ou List(1, 2, 3)que retornam scala.collection.immutable.$colon$colon, portanto, pode-se escrever:

var x: scala.collection.immutable.$colon$colon[Int] = null
x = Seq(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]
x = List(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]

Como resultado, eu argumentaria que a única coisa que importa são os métodos que você deseja expor, por exemplo, para adicionar um prefixo que você pode usar ::da Lista que eu acho redundante no +:Seq e pessoalmente adiro ao Seq por padrão.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.