2010-09-30 9 views
7

Nel mio programma utilizzo spesso le raccolte per memorizzare elenchi di oggetti. Attualmente utilizzo ArrayList per memorizzare oggetti. La mia domanda è: questa è la scelta migliore? Potrebbe essere meglio usare LinkedList? O qualcos'altro?Quale implementazione di List utilizzare?

criteri da prendere in considerazione sono:

  • Utilizzo della memoria
  • prestazioni

operazioni di cui ho bisogno sono:

  • Aggiungi elemento da collezione
  • iterazioni sugli elementi

Qualche idea?

Aggiornamento: la mia scelta è: ArrayList :) Sulla base di questa discussione, così come i seguenti:

+3

Possibile duplicato. http://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist – Fil

+0

Elaborare su "Produttività" per favore –

+0

si aggiunge per lo più alla fine della lista o in qualsiasi posizione arbitraria? –

risposta

8

ho sempre predefinito a ArrayList, e sarebbe nel tuo caso pure, tranne quando

  • ho bisogno di filo di sicurezza (nel qual caso mi metto a guardare Elenco implementazioni in java.util.concurrent)
  • So che sto facendo un sacco di inserimento e manipolazione per la List o profiling rivela il mio utilizzo di un ArrayList per essere un problema (molto raro)

Per quanto riguarda cosa scegliere in questo secondo caso, questo Il thread SO.com ha alcune informazioni utili: List implementations: does LinkedList really perform so poorly vs. ArrayList and TreeList?

+0

Grazie per il collegamento a una discussione molto interessante! –

+0

in che modo LinkedList è più thread-safe? – Thilo

+0

@Thilo - Non ho mai detto che lo fosse. Ho detto di default su ArrayList a meno che non avessi bisogno della sicurezza del thread. Solo per renderlo più chiaro, modifico la mia risposta per dire che vado alle implementazioni di List in java.util.concurrent. – whaley

0

lista collegata è più veloce per l'aggiunta/rimozione di elementi interni (cioè non testa o coda)

L'arraylist è più veloce per iterare

+1

Hm. Forse è più veloce quando itera, anche se non mi aspetto che questo sia più che marginale. Il vero vantaggio dovrebbe essere con l'accesso a elementi in ordine casuale ... – Dirk

+0

Come ho capito entrambi hanno O (n) iterazione. – Qwerky

+0

O (n) iterazione su N elementi. L'iteratore dell'elenco collegato non verrà lanciato se si legge qui e si cambia modo da lì ... – GregC

0

È un compromesso classico tra l'inserimento e l'ottimizzazione del recupero. Scelta comune per l'attività mentre la descrivi è l'ArrayList.

+0

Perché è una scelta comune? –

+0

È veloce per iterare su tutta la raccolta, e c'è meno ingombro di memoria dal momento che i collegamenti in un elenco collegato devono essere memorizzati da qualche parte. – GregC

0

ArrayList va bene per il vostro (e la maggior parte degli altri) scopi. Ha un overhead di memoria molto piccolo e ha buone prestazioni ammortizzate per la maggior parte delle operazioni. I casi in cui non è l'ideale sono relativamente rari:

  • L'elenco ist molto grande
  • avete spesso bisogno di fare una di queste operazioni:
    • aggiungere/rimuovere gli elementi durante l'iterazione
    • Rimuovi elementi a partire dall'inizio della lista
+0

Per elaborare su questo punto: l'iteratore di ArrayList genererà un'eccezione se rileva il cambiamento mentre itera. Inoltre, rimuovere dall'inizio la coda a-la è meglio realizzata tramite l'elenco collegato per ovvi motivi. – GregC

+0

@GregC: un iteratore di LinkedList non genera eccezioni quando sono presenti modifiche simultanee? Se è così, perché è così buono? – Thilo

+0

Sembra che io abbia torto ... Dovrò provarlo .... citando: "Gli iteratori restituiti dall'iter iteratore di questa classe e i metodi listIterator sono veloci: se l'iteratore è strutturalmente modificato in qualsiasi momento dopo l'iteratore creato, in qualsiasi modo, tranne che attraverso i metodi di rimozione o aggiunta di Iterator, l'iteratore genererà una ConcurrentModificationException, quindi, a fronte di modifiche simultanee, l'iteratore fallisce rapidamente e in modo pulito, piuttosto che rischiare un comportamento arbitrario non deterministico a un indeterminato tempo in futuro. " – GregC

0

se si sta solo aggiungendo alla fine della lista, ArrayList dovrebbe essere ok. Dalla documentazione di ArrayList:

I dettagli della politica di crescita non sono specificati al di là del fatto che l'aggiunta di un elemento ha costante di tempo costo ammortizzato

e ArrayList dovrebbe anche utilizzare meno memoria di una lista collegata in quanto non è necessario utilizzare lo spazio per i collegamenti.

0

Dipende dal profilo di utilizzo.

Aggiungi alla fine della lista? Entrambi stanno bene per questo. Aggiungete all'inizio della lista? LinkedList è meglio per questo. Richiede l'accesso casuale (chiamerai mai get(n) su di esso)? ArrayList è meglio per questo.

Entrambi sono validi per l'iterazione, entrambe le implementazioni di Iterator sono O (1) per next().

In caso di dubbio, testare la propria app per ogni implementazione e fare la propria scelta.

0

so che sono in ritardo, ma, forse, this page può aiutare, non solo ora, ma in futuro ...

0

Dato i criteri, si dovrebbe utilizzare la lista collegata.

LinkedList implementa l'interfaccia Deque che significa che può aggiungere all'inizio o alla fine dell'elenco in tempo costante (1). Inoltre, sia ArrayList che LinkedList eseguiranno l'iterazione entro (N).

NON si deve utilizzare ArrayList semplicemente perché il costo dell'aggiunta di un elemento quando l'elenco è pieno. In questo caso, l'aggiunta dell'elemento sarebbe (N) a causa della creazione del nuovo array e della copia di tutti gli elementi da un array all'altro.

Inoltre, ArrayList occuperà più memoria in quanto la dimensione dell'array di supporto potrebbe non essere completa.

+0

Il mio collega ha appena scritto un semplice test, aggiungendo elementi a elenchi di dimensioni diverse in luoghi diversi. Ed ecco il risultato: Ho fatto il mio test senza pretese. Ecco il risultato: - Semplice aggiunta (List.add ("A")): ArrayList più veloce di LinkedList 3-5 volte nell'intervallo di dimensioni da 1 a 100 000. –

+0

Aggiunta alla lista di testa (List.add (0, "A"): Alla dimensione 1 il tempo è uguale; Alla dimensione 100 LinkedList più veloce ~ 2 volte; Alla dimensione 1000 LinkedList più veloce ~ 10 volte; Alla dimensione 10000 LiskedList più veloce ~ 50 volte; Alla dimensione 50000 LinkedList più veloce ~ 80 times –

+0

Aggiunta casuale (List.add (Math.random (list.size()), "A")): ArrayList più veloce di LinkedList 2 volte sullo stesso intervallo (da 1 a 100.000) –

Problemi correlati