2012-06-15 13 views
28

(tómelo como seguimiento a esta pregunta - No Scala mutable list)¿Qué lista de cambios de scala usar?

Quiero usar una lista mutable en scala. Puedo elegir

cual es bueno, pero lo que es la recomendada, Scala manera "estándar" idiomática? Solo quiero usar una lista a la que pueda añadir cosas en la parte posterior.

Editar:

bien, para ampliar aún más.

Estoy usando un HashMap, donde las "listas" (lo que quiero decir en sentido general) estarán en el lado del valor. Luego, estoy leyendo algo de un archivo y para cada línea, quiero encontrar la lista correcta en el hashmap y anexar el valor a la lista.

+2

Probablemente deberías expandirte sobre cómo vas a usarlo, porque en un sentido general, la manera idiomática de Scala no es usar listas mutables (en cambio usa pliegues o recursión con listas inmutables). –

+0

Creo que sus listas pueden ser inmutables. Simplemente puede preceder a una lista inmutable y actualizar su entrada HashMap a esa lista recién creada. – ziggystar

+0

Bueno, en ese caso, tendré que cambiar el hashmap en lugar de las listas. En este momento, no cambio el hashmap, pero cambio las listas. –

Respuesta

14

Por el bien de los lectores que visitan esta vieja pregunta: La sección de la documentación Concrete Mutable Collection Classes tiene una visión general de las clases de lista mutable, incluyendo explicaciones sobre cuándo usarla.

+0

¡Oh genial! Estoy pensando en aceptar esta respuesta en su lugar, 3 años más tarde –

+0

Aceptado. Lo siento por @ axel22, pero hizo su mejor esfuerzo en 2012 –

33

Depende de lo que necesite.

DoubleLinkedList es una lista vinculada que le permite recorrer ida y vuelta a través de la lista de nodos. Use sus referencias prev y next para ir al nodo anterior o siguiente, respectivamente.

LinkedList es una lista vinculada individualmente, por lo que no hay prev punteros - si solo recorre el siguiente elemento de la lista todo el tiempo, esto es lo que necesita.

EDIT: Tenga en cuenta que los dos anteriores están destinados a ser utilizados internamente como bloques de construcción para estructuras de lista más complicados como MutableList s que apoyan append eficiente y mutable.Queue s.

Las dos colecciones anteriores tienen operaciones de adición de tiempo lineal.

ListBuffer es una clase de memoria intermedia. Aunque está respaldado por una estructura de datos de lista enlazada de forma individual, no expone el puntero next al cliente, por lo que solo puede recorrerlo mediante iteradores y el foreach. Su uso principal es, sin embargo, como un buffer y un creador de listas inmutables: usted agrega elementos a través del +=, y cuando llama al result, obtiene de manera eficiente un immutable.List funcional. A diferencia de las listas mutables e inmutables, tanto las operaciones de agregar como las de anteponer son de tiempo constante; puede agregarlas al final a través del += de manera muy eficiente.

MutableList se usa internamente, por lo general, no lo use a menos que pretenda implementar una clase de colección personalizada en base a la estructura de datos de lista de enlace simple. Las colas mutables, por ejemplo, heredan esta clase. La clase MutableList también tiene una operación eficiente de adición de tiempo constante, porque mantiene una referencia al último nodo en la lista.

+0

¿Las listas vinculadas realmente tienen un apéndice lineal? ¿Por qué? Tanto las listas de enlaces simples como dobles pueden admitir anexos en tiempo constante, al menos en un mundo completamente mutable. – svick

+0

Sí, lo hacen; consulte aquí: https://github.com/scala/scala/blob/v2.9.2/src/library/scala/collection/mutable/LinkedListLike.scala#L1. ¿Por qué? La decisión de diseño fue hacer que cada nodo fuera una lista vinculada en sí misma; de lo contrario, necesitaría un contenedor alrededor de las referencias de nodo inicial y final, que es exactamente lo que es 'MutableList'. – axel22

+0

No veo una respuesta en los documentos para "qué lista es la mejor para eliminar elementos", p. si planeo construir una lista, ¿entonces eliminar toneladas de elementos de a uno por vez? – Hamy

9

Si desea agregar elementos, no debe usar un List en absoluto. List s son buenos cuando desea anteponer elementos.Use ArrayBuffer en su lugar.

+5

No estoy de acuerdo. Si no necesita acceso aleatorio, 'ListBuffer' tiene mejores características de rendimiento que' ArrayBuffer', que necesita cambiar el tamaño de vez en cuando. Claro, las operaciones de adición pueden ejecutarse en tiempo constante * amortizado * o algo así, lo que no está mal, pero no veo ninguna ventaja de 'ArrayBuffer' aquí. – rolve

+5

@rolve El tiempo constante amortiguado es a menudo más rápido al final, porque las constantes involucradas para asignar un nuevo objeto en la JVM (y tratar con la presión GC asociada) son bastante altas, mientras que las operaciones de cambio de tamaño ocurren muy raramente (en promedio cada elemento se copia dos veces). Por no mencionar los beneficios de la ubicación en caché de ArrayBuffer, que puede ser enorme en las CPU modernas. –

+2

@JohnColanduoni Con casi 3 años pasados ​​desde mi comentario, estoy de acuerdo en que 'ArrayBuffer' es probablemente la mejor opción. De todos modos, las mediciones de rendimiento real se deben utilizar como base para esta discusión. :) – rolve

2

Solo quiero usar una lista a la que pueda agregar cosas en la parte posterior.

A continuación, elija algo que implemente Growable. Yo personalmente sugiero una de las implementaciones Buffer.

Me mantengo alejado de LinkedList y DoubleLinkedList, ya que están presentes principalmente como la implementación subyacente de otras colecciones, pero tienen bastantes errores hasta Scala 2.9.x. Comenzando con Scala 2.10.0, espero que las diversas correcciones de errores los hayan actualizado al estándar. Aún así, carecen de algunos métodos que la gente espera, como +=, que encontrará en colecciones basadas en ellos.

Cuestiones relacionadas