2010-11-03 21 views
5

¿Por qué hay una falta de coherencia entre Conjuntos y Listas en la API de Colecciones de Scala?Incoherencias de Colecciones Scala

Por ejemplo, hay un conjunto inmutable, pero también uno mutable. Si quiero utilizar este último, puedo simplemente hacer esto:

val set = Set[A]() 
set += new A 

Sin embargo, no hay ninguna lista mutable, per se. Si quiero escribir un fragmento de código similar usando Listas, ¿qué estructura de datos usar? LinkedList suena como un buen candidato, porque es mutable, pero no tiene definido ningún método + =. ListBuffer parece satisfacer los requisitos, pero no es una lista.

Después de leer 2.8 Collections docs Llego a la conclusión MutableList es probablemente la mejor opción.

Todavía de alguna manera deseo que haya scala.collection.mutable.List.

+1

¿Y no mutable.MutableSet? :-) –

Respuesta

20

La razón de esto es que Java ha cooptado el tipo funcional List en el sentido de algo que no lo es (es decir, java.util.List no es una lista ).

Probablemente no tiene sentido para un lenguaje de programación funcional para tener una mutableList como tal tipo es un oxímoron. De ahí ListBuffer o ArrayBuffer. O simplemente use IndexedSeq, de los cuales existen implementaciones mutables e inmutables

3

ArraySeq puede ser lo que estás buscando, excepto que + = es excepcionalmente lento. También podría usar java.util.ArrayList e importar collection.JavaConversions._

Parece que Scala carece de una buena colección mutable de tipo lista con índice de tiempo constante (como ArrayList for java).

En cualquier caso, tenga en cuenta que "Lista" se refiere exactamente al tipo "scala.immutable.List". Por lo tanto, Seq (o algún otro tipo de colección más abstracto) es el tipo que debe esperar en métodos en lugar de "List" si desea generalizar colecciones inmutables/mutables.

Más ideal es requring un IndexedSeq, lo que significa que la operación de índice es eficaz para esa colección. Sin embargo, no estoy seguro de que ListBuffer caiga en esa categoría.

+0

¿Qué hay de ArrayBuffer? –

+3

La "buena colección mutable lista de Scala" "como ArrayList for java" es ArrayBuffer. –

+0

ArrayBuffer es ideal para agregar, pero no tan bueno para anteponer. ArrayList de Java realmente intentará amortizar los costos de antemano también, haciéndolo un poco mejor en mi opinión. Sí ArrayBuffer es probablemente lo suficientemente bueno si solo agregas elementos a una lista y a indexación. – jsuereth

2

Porque Set es solo un rasgo: es abstracto y requiere una implementación. Entonces uno puede hablar de clases que son mutable.Set o immutable.Set.

Mientras tanto, List es una clase, una implementación del rasgo (abstracto) immutable.LinearSeq. Nunca puede haber otra clase que también sea List. Sin embargo, descubrirá que hay es un rasgo mutable.LinearSeq.

En términos de Java, está comparando las interfaces con las clases, son distintas.

+0

La distinción en la secc. 16.8 del libro de la escalera, objeto de la Lista global (los métodos no funcionan en todos los objetos de la Lista) vs. clase de la Lista, vale la pena mencionar. –

9

La secuencia/lista analógica de Set en las bibliotecas de colecciones de Scala es Seq. List es solo una implementación particular e inmutable de Seq, como es Vector. ArrayBuffer o ListBuffer son implementaciones típicas de mutable.Seq.

+0

Gracias por la simple aclaración, esto siempre me ha molestado. –

0

No se olvide de scala.collection.mutable.{LinkedList,DoubleLinkedList}. Son mutables, y son LinearSeq. La mutación es un poco extraña: puede modificar la cabecera asignando a la referencia elem, y la cola asignándola a la referencia next.

Por ejemplo, este bucle cambia todos los valores negativos a cero.

val lst = collection.mutable.LinkedList(1, -2, 7, -9) 
var cur = lst 
while (cur != Nil) { 
    if (cur.elem < 0) cur.elem = 0 
    cur = cur.next 
} 

Este ciclo elimina cada segundo elemento de la lista.

var cur = lst 
while (cur != Nil && cur.next != Nil) { 
    cur.next = cur.next.next 
    cur = cur.next 
} 

No estoy sugiriendo que estas sean mejores que la lista inmutable. Solo estoy señalando que Scala tiene listas mutables que se parecen bastante a lo que has visto en tu clase de estructuras de datos.

Cuestiones relacionadas