¿Qué colección Java debo usar?

127

En esta pregunta, ¿cómo puedo seleccionar eficientemente un contenedor de biblioteca estándar en C ++ 11? es un diagrama de flujo útil para usar al elegir colecciones de C ++.

Pensé que este era un recurso útil para las personas que no están seguras de qué colección deberían usar, así que intenté encontrar un diagrama de flujo similar para Java y no pude hacerlo.

¿Qué recursos y "hojas de trucos" están disponibles para ayudar a las personas a elegir la Colección correcta para usar al programar en Java? ¿Cómo saben las personas qué implementaciones de listas, conjuntos y mapas deben usar?

Tim B
fuente
El libro Java Generics and Collections (Naftalin & Wadler) tiene un capítulo sobre esto.
Christophe Roussy

Respuestas:

293

Como no pude encontrar un diagrama de flujo similar, decidí hacer uno yo mismo.

Este diagrama de flujo no intenta abarcar cosas como el acceso sincronizado, la seguridad de subprocesos, etc. o las colecciones heredadas, pero cubre los 3 conjuntos estándar , los 3 mapas estándar y las 2 listas estándar .

ingrese la descripción de la imagen aquí

Esta imagen fue creada para esta respuesta y está licenciada bajo una licencia internacional Creative Commons Attribution 4.0. La atribución más simple es vincularse a esta pregunta o a esta respuesta.

Otros recursos

Probablemente la otra referencia más útil es la siguiente página de la documentación de Oracle que describe cada Colección .

HashSet vs TreeSet

Hay una discusión detallada de cuándo usar HashSeto TreeSetaquí: Hashset vs Treeset

ArrayList vs LinkedList

Discusión detallada: ¿ Cuándo usar LinkedList sobre ArrayList?

Tim B
fuente
¡Agradable! Pero debo estar en desacuerdo con sus decisiones LinkedListvs. ArrayListPrimero, si la lista es de un tamaño significativo, LinkedListes preferible. LinkedListtiene una sobrecarga por elemento, por lo que es asintóticamente peor en términos de consumo de memoria que un ArrayList. Además, si la mayor parte del acceso se encuentra al final de la lista, ArrayListes preferible un porque proporciona acceso aleatorio a elementos de tiempo constante. Acceder al nelemento th de a LinkedListes una O(n)operación. ... De hecho, la decisión de usar una lista vinculada siempre debería ser "no".
Matt Ball
2
@MattBall Estoy de acuerdo con usted en su mayor parte. Sin embargo, Java LinkedListes una lista de doble enlace, por lo que el acceso al inicio y al final son rápidos. Notarás que de las ramas de arriba, las tres preguntas tienen que responder sí antes de recomendar el uso de LinkedList- así que, en otras palabras, estoy de acuerdo contigo en que en la mayoría de los casos la respuesta es no. Cosas como colas y colas en las que constantemente está agregando y eliminando cosas de los extremos del área de lista para un buen caso de uso LinkedList.
Tim B
@MattBall El uso de la memoria es una situación mucho más complicada ya que mientras LinkedListusa más memoria por elemento ... ArrayListnunca libera memoria. Eso significa que si tiene una lista que a veces crece a un tamaño enorme, pero generalmente es pequeña, entonces el ArrayListrendimiento de la memoria será peor. La sobrecarga de memoria de Listsí mismo es generalmente (aunque no siempre) pequeña en comparación con la de los elementos que contiene también.
Tim B
Map<K,V>no es parte dejava.util.collection
Mehraj Malik
@MehrajMalik Hmm, el etiquetado es ambiguo, estoy de acuerdo. Me refería a Colección dentro de java.util. ie java.util. * inserte el nombre de la colección aquí *
Tim B
66

Resumen de las principales colecciones no concurrentes, no sincronizadas

Collection: Una interfaz que representa una "bolsa" desordenada de elementos, llamada "elementos". El elemento "siguiente" no está definido (al azar).

  • Set: Una interfaz que representa Collectiona sin duplicados.
    • HashSet: A Setrespaldado por a Hashtable. El uso de memoria más rápido y más pequeño, cuando ordenar no es importante.
    • LinkedHashSet: A HashSetcon la adición de una lista vinculada para asociar elementos en orden de inserción . El elemento "siguiente" es el siguiente elemento insertado más recientemente.
    • TreeSet: A Setdonde los elementos están ordenados por a Comparator(típicamente ordenamiento natural ). Uso de memoria más lento y más grande, pero necesario para pedidos basados ​​en comparadores.
    • EnumSet: Un extremadamente rápido y eficiente Setpersonalizado para un solo tipo de enumeración.
  • List: Una interfaz que representa un Collectioncuyos elementos están ordenados y cada uno tiene un índice numérico que representa su posición, donde cero es el primer elemento y (length - 1)es el último.
    • ArrayList: ListRespaldado por una matriz, donde la matriz tiene una longitud (llamada "capacidad") que es al menos tan grande como la cantidad de elementos (el "tamaño" de la lista). Cuando el tamaño excede la capacidad (cuando (capacity + 1)-thse agrega el elemento), la matriz se recrea con una nueva capacidad de (new length * 1.5)--esta recreación es rápida, ya que utiliza System.arrayCopy(). Eliminar e insertar / agregar elementos requiere que todos los elementos vecinos (a la derecha) se desplacen dentro o fuera de ese espacio. Acceder a cualquier elemento es rápido, ya que solo requiere el cálculo (element-zero-address + desired-index * element-size)para encontrar su ubicación. En la mayoría de las situaciones , ArrayListse prefiere a sobre LinkedList.
    • LinkedList: A Listrespaldado por un conjunto de objetos, cada uno vinculado a sus vecinos "anteriores" y "siguientes". A LinkedListtambién es a Queuey Deque. El acceso a los elementos se realiza comenzando por el primer o el último elemento, y atravesando hasta alcanzar el índice deseado. La inserción y eliminación, una vez que se alcanza el índice deseado a través del recorrido, es una cuestión trivial de reasignar solo los enlaces vecinos inmediatos para apuntar al nuevo elemento o evitar el elemento ahora eliminado.
  • Map: Una interfaz que representa un Collection donde cada elemento tiene una "clave" de identificación: cada elemento es un par clave-valor.
    • HashMap: UNA Map donde las claves están desordenadas y respaldadas por a Hashtable.
    • LinkedhashMap: Las claves están ordenadas por orden de inserción .
    • TreeMap: A Mapdonde las claves se ordenan por a Comparator(orden típicamente natural).
  • Queue: Una interfaz que representa un Collection elementos donde normalmente se agregan a un extremo y se eliminan del otro (FIFO: primero en entrar, primero en salir).
  • Stack: Una interfaz que representa un Collection donde los elementos son, típicamente, tanto agregados (empujados) como eliminados (reventados) del mismo extremo (LIFO: último en entrar, primero en salir).
  • Deque: Abreviatura de "cola doble", generalmente se pronuncia "cubierta". Una lista vinculada que generalmente solo se agrega y se lee desde cualquier extremo (no desde el medio).

Diagramas básicos de recolección:

diagrama

Comparando la inserción de un elemento con an ArrayListy LinkedList:

diagrama

mente mental
fuente
2
El mejor resumen breve que se puede obtener en cualquier lugar :)
roottraveller
11

Una imagen aún más simple está aquí. ¡Intencionalmente simplificado!

  1. Colección es cualquier cosa que contenga datos llamados "elementos" (del mismo tipo). No se asume nada más específico.

  2. La lista es unacolección indexada de datos donde cada elemento tiene un índice. Algo así como la matriz, pero más flexible.

    Los datos en la lista mantienen el orden de inserción.

    Operación típica: obtener el enésimo elemento.

  3. Set es una bolsa de elementos , cada elemento solo una vez (los elementos se distinguen usando suequals() método.

    Los datos en el conjunto se almacenan principalmente para saber qué datos hay.

    Operación típica: saber si un elemento está presente en la lista.

  4. El mapa es algo así como la Lista, pero en lugar de acceder a los elementos por su índice entero, puede acceder a ellos por su clave , que es cualquier objeto. Al igual que la matriz en PHP :)

    Los datos en el mapa se pueden buscar por su clave.

    Operación típica: obtener un elemento por su ID (donde la ID es de cualquier tipo, no solo intcomo en el caso de List).

Las diferencias

  • Establecer y Mapa: en Establecer, puede buscar datos por sí mismos , mientras que en el Mapa por su clave .

  • Lista y mapa: en la lista puede acceder al elemento por su intíndice (posición en la lista), mientras que en el mapa por su clave, que es de cualquier tipo (normalmente: ID)

  • List and Set: en List, los elementos están vinculados por su posición y pueden duplicarse, mientras que en Set los elementos son simplemente "presentes" (pr no presentes) y son únicos (en el sentido de equals(), o compareTo()para SortedSet)

Honza Zidek
fuente
1

Es simple: si necesita almacenar valores con las teclas asignadas a ellos, vaya a la interfaz de Mapa, de lo contrario use Lista para valores que pueden estar duplicados y finalmente use la interfaz Establecer si no desea valores duplicados en su colección.

Aquí está la explicación completa http://javatutorial.net/choose-the-right-java-collection , incluido el diagrama de flujo, etc.

filip_j
fuente
1

Mapa

Si elijo una Map, hice esta tabla que resume las características de cada una de las diez implementaciones incluidas con Java 11.

Tabla de implementaciones de mapas en Java 11, comparando sus características

Albahaca Bourque
fuente
0

Colecciones comunes, colecciones comunes ingrese la descripción de la imagen aquí

Aliaksandr Shpak
fuente
-2

¿Qué colección Java debo usar?

Depende de qué problema está tratando de resolver o qué requisitos tiene.

Ejemplos:

  1. ¿Desea ordenar los elementos mientras los almacena? HashSet
  2. ¿Desea que se almacenen los pares (Clave, Valor)? HashMap
  3. ¿Desea preservar el orden de los elementos cuando se inserta? ArrayList, LinkedList
  4. ¿Desea que se ordenen las claves en el par (clave, valor)? - texto fuerte
  5. ¿Desea implementar una pila para resolver su problema? - Pila
  6. ¿Desea tener acceso FIFO (primero en entrar, primero en salir)? - Cola
  7. ¿Desea que solo se almacenen elementos ÚNICOS? - HashSet
  8. ¿Desea permitir la clave como "Nulo" durante el almacenamiento (Clave, Valor)? - HashMap
  9. ¿Desea que no haya valores NULL para el par (clave, valor)? Tabla de picadillo
Aviral Kumar
fuente
Incluso con texto fuerte en el ítem 4 reemplazado por, digamos, ConcurrentSkipListMap (K, V) , ¿qué agrega esta respuesta al gráfico de decisión de Tim B , a las "descripciones de lista corta" de aliteralmind ?
barba gris el
Su primer punto, HashSet no clasifica los datos, incluso el orden de inserción no se mantiene. Deberías cambiarlo con TreeSet
Saurabh Mishra