Quale raccolta Java dovrei usare?


127

In questa domanda Come posso selezionare in modo efficiente un contenitore di libreria standard in C ++ 11? è un utile diagramma di flusso da utilizzare quando si scelgono raccolte C ++.

Ho pensato che questa fosse una risorsa utile per le persone che non sono sicure di quale raccolta debbano utilizzare, quindi ho cercato di trovare un diagramma di flusso simile per Java e non sono stato in grado di farlo.

Quali risorse e "cheat sheet" sono disponibili per aiutare le persone a scegliere la giusta collezione da utilizzare durante la programmazione in Java? Come fanno le persone a sapere quali implementazioni di Elenco, Set e Mappa dovrebbero usare?


Il libro Java Generics and Collections (Naftalin & Wadler) ha un capitolo su questo.
Christophe Roussy,

Risposte:


293

Dato che non riuscivo a trovare un diagramma di flusso simile, ho deciso di crearne uno da solo.

Questo diagramma di flusso non cerca di coprire cose come l'accesso sincronizzato, la sicurezza dei thread ecc. O le raccolte legacy, ma copre i 3 set standard , 3 mappe standard e 2 elenchi standard .

inserisci qui la descrizione dell'immagine

Questa immagine è stata creata per questa risposta ed è sotto licenza Creative Commons Attribution 4.0 International License. L'attribuzione più semplice è collegando a questa domanda o questa risposta.

Altre risorse

Probabilmente l'altro riferimento più utile è la pagina seguente della documentazione dell'oracolo che descrive ciascuna Collezione .

HashSet vs TreeSet

C'è una discussione dettagliata su quando usare HashSeto TreeSetqui: Hashset vs Treeset

ArrayList vs LinkedList

Discussione dettagliata: quando utilizzare LinkedList su ArrayList?


Bello! Ma non sono d'accordo con le tue decisioni LinkedListvs. ArrayListInnanzitutto, se l'elenco ha dimensioni significative, LinkedListè preferibile. LinkedListha un sovraccarico per elemento, quindi è asintoticamente peggiore in termini di consumo di memoria di un ArrayList. Inoltre, se la maggior parte dell'accesso si trova alla fine dell'elenco, ArrayListè preferibile utilizzare un accesso casuale agli elementi a tempo costante. L'accesso nall'elemento th di a LinkedListè O(n)un'operazione. ... In effetti, la decisione di utilizzare un elenco collegato dovrebbe essere praticamente sempre "no".
Matt Ball,

2
@MattBall Sono d'accordo con te per la maggior parte. Tuttavia Java LinkedListè un doppio elenco collegato, quindi l'accesso all'inizio e alla fine sono entrambi veloci. Noterai che delle filiali sopra tutte e tre le domande devono rispondere di sì prima di raccomandare di usare il LinkedList- quindi in altre parole sono d'accordo con te che nella maggior parte dei casi la risposta è no. Cose come le code e i dequeues in cui si aggiungono e rimuovono costantemente gli oggetti dalle estremità dell'area dell'elenco per cui è utile LinkedList.
Tim B

@MattBall L'utilizzo della memoria è una situazione molto più complicata poiché mentre si LinkedListutilizza più memoria per elemento ... ArrayListnon rilascia mai memoria. Ciò significa che se si dispone di un elenco che a volte diventa di dimensioni enormi ma di solito è piccolo, si ArrayListotterranno prestazioni di memoria peggiori. Il sovraccarico di memoria dello Liststesso è di solito (anche se non sempre) piccolo rispetto a quello degli elementi che contiene.
Tim B

Map<K,V>non fa parte dijava.util.collection
Mehraj Malik,

@MehrajMalik Hmm, l'etichettatura è ambigua sono d'accordo. Intendevo Collection all'interno di java.util. cioè java.util. * inserisci qui il nome della raccolta *
Tim B

66

Riepilogo delle principali raccolte non simultanee e non sincronizzate

Collection: Un'interfaccia che rappresenta una "borsa" di oggetti non ordinata, chiamata "elementi". L'elemento "successivo" non è definito (casuale).

  • Set: Un'interfaccia che rappresenta un Collectionsenza duplicati.
    • HashSet: A Setsostenuto da a Hashtable. L'utilizzo della memoria più veloce e più piccolo, quando l'ordine non è importante.
    • LinkedHashSet: A HashSetcon l'aggiunta di un elenco collegato per associare elementi nell'ordine di inserimento . L'elemento "successivo" è l'elemento inserito più di recente.
    • TreeSet: A in Setcui gli elementi sono ordinati per Comparator( ordinamento normalmente naturale ). Utilizzo della memoria più lento e più grande, ma necessario per l'ordinamento basato sul comparatore.
    • EnumSet: Estremamente veloce ed efficiente Setpersonalizzato per un singolo tipo di enum.
  • List: Un'interfaccia che rappresenta un i Collectioncui elementi sono ordinati e ognuno ha un indice numerico che rappresenta la sua posizione, dove zero è il primo elemento ed (length - 1)è l'ultimo.
    • ArrayList: ListSupportato da un array, in cui l'array ha una lunghezza (chiamata "capacità") che è almeno pari al numero di elementi (la "dimensione" dell'elenco). Quando la dimensione supera la capacità (quando (capacity + 1)-thviene aggiunto l' elemento), l'array viene ricreato con una nuova capacità: (new length * 1.5)questa ricreazione è veloce, poiché utilizza System.arrayCopy(). L'eliminazione e l'inserimento / l'aggiunta di elementi richiede che tutti gli elementi vicini (a destra) vengano spostati all'interno o all'esterno di quello spazio. L'accesso a qualsiasi elemento è veloce, in quanto richiede solo il calcolo (element-zero-address + desired-index * element-size)per trovare la sua posizione. Nella maggior parte dei casi , ArrayListè preferibile un a LinkedList.
    • LinkedList: Un Listsupporto di una serie di oggetti, ognuno collegato ai suoi vicini "precedenti" e "successivi". A LinkedListè anche a Queuee Deque. L'accesso agli elementi avviene a partire dal primo o dall'ultimo elemento e attraversa fino a raggiungere l'indice desiderato. Inserimento ed eliminazione, una volta raggiunto l'indice desiderato attraverso l'attraversamento, è una questione banale rimappare solo i collegamenti dei vicini immediati per puntare al nuovo elemento o bypassare l'elemento ora cancellato.
  • Map: Un'interfaccia che rappresenta un punto in Collectioncui ogni elemento ha una "chiave" identificativa - ogni elemento è una coppia chiave-valore.
    • HashMap: A Mapdove i tasti non sono ordinati e sono supportati da a Hashtable.
    • LinkedhashMap: Le chiavi sono ordinate per ordine di inserzione .
    • TreeMap: A Mapdove le chiavi sono ordinate da un Comparator(ordinamento normalmente naturale).
  • Queue: Un'interfaccia che rappresenta un punto in Collectioncui gli elementi vengono, in genere, aggiunti a un'estremità e rimossi dall'altra (FIFO: first-in, first-out).
  • Stack: Un'interfaccia che rappresenta un punto in Collectioncui gli elementi vengono, in genere, aggiunti (spinti) e rimossi (saltati) dalla stessa estremità (LIFO: last-in, first-out).
  • Deque: Abbreviazione di "coda doppia", generalmente pronunciato "mazzo". Un elenco collegato che viene in genere aggiunto e letto solo da entrambe le estremità (non dal centro).

Diagrammi di raccolta di base:

diagramma

Confronto dell'inserimento di un elemento con un ArrayListe LinkedList:

diagramma


2
Il meglio in breve che uno può arrivare ovunque :)
roottraveller,

11

Un'immagine ancora più semplice è qui. Volutamente semplificato!

  1. La raccolta è qualsiasi cosa che contiene dati chiamati "elementi" (dello stesso tipo). Non si assume nulla di più specifico.

  2. L'elenco è indicizzato raccolta di dati in cui ogni elemento ha un indice. Qualcosa come l'array, ma più flessibile.

    I dati nell'elenco mantengono l'ordine di inserimento.

    Operazione tipica: ottenere l'n-esimo elemento.

  3. Set è una borsa di elementi , ogni elemento solo una volta (gli elementi si distinguono usando il loroequals() metodo.

    I dati nel set sono memorizzati principalmente solo per sapere quali dati ci sono.

    Operazione tipica: indica se un elemento è presente nell'elenco.

  4. Mappa è qualcosa di simile all'elenco, ma invece di accedere agli elementi tramite il loro indice intero, puoi accedervi con la loro chiave , che è qualsiasi oggetto. Come l'array in PHP :)

    I dati nella mappa sono ricercabili dalla loro chiave.

    Operazione tipica: ottenere un elemento dal suo ID (dove ID è di qualsiasi tipo, non solo intcome nel caso di Elenco).

Le differenze

  • Set e Mappa: in Set puoi cercare i dati da soli , mentre in Mappa con la loro chiave .

  • Elenco e Mappa: in Elenco accedi all'elemento in base al loro intindice (posizione in Elenco), mentre in Mappa con la loro chiave quale sistema operativo di qualsiasi tipo (in genere: ID)

  • Elenco e Set: in Elenco gli elementi sono vincolati dalla loro posizione e possono essere duplicati, mentre in Set gli elementi sono semplicemente "presenti" (pr non presente) e sono unici (nel significato di equals(), o compareTo()per SortedSet)


1

È semplice: se è necessario memorizzare valori con chiavi mappate su di essi, utilizzare l'interfaccia Mappa, altrimenti utilizzare Elenco per i valori che possono essere duplicati e infine utilizzare l'interfaccia Set se non si desidera valori duplicati nella raccolta.

Ecco la spiegazione completa http://javatutorial.net/choose-the-right-java-collection , incluso diagramma di flusso ecc.


1

Carta geografica

Se si sceglie a Map, ho creato questa tabella che riassume le funzionalità di ciascuna delle dieci implementazioni in bundle con Java 11.

Tabella delle implementazioni delle mappe in Java 11, confrontando le loro caratteristiche



-2

Quale raccolta Java dovrei usare?

Dipende dal problema che stai cercando di risolvere o dai requisiti che hai.

Esempi:

  1. Vuoi che gli elementi vengano ordinati durante la loro memorizzazione? HashSet
  2. Vuoi che le coppie (chiave, valore) siano memorizzate? HashMap
  3. Vuoi preservare l'ordine degli elementi quando inseriti? ArrayList, LinkedList
  4. Vuoi ordinare le chiavi nella coppia (chiave, valore)? - testo forte
  5. Vuoi implementare uno Stack per risolvere il tuo problema? - Stack
  6. Vuoi avere l'accesso FIFO (First in First out)? - Coda
  7. Vuoi conservare solo gli elementi UNICI? - HashSet
  8. Vuoi consentire la chiave come "Null" durante la memorizzazione (chiave, valore)? - HashMap
  9. Vuoi nessun valore NULL per la coppia (chiave, valore)? HashTable

Anche con un testo forte nel punto 4 sostituito da, diciamo, ConcurrentSkipListMap (K, V) , cosa aggiunge questa risposta al grafico decisionale di Tim B , alle "descrizioni di lista ristretta " di aliteralmind ?
Greybeard,

Il tuo primo punto, HashSet non ordina i dati, anche l'ordine di inserimento non viene mantenuto. Dovresti cambiarlo con TreeSet
Saurabh Mishra
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.