efficiente rimozione di un certo numero di elementi da un ArrayList
richiede una riflessione. L'approccio ingenuo è qualcosa di simile:
Iterator<DealerProductCount> it = wsResponse.Dealers.iterator();
while (it.hasNext()) {
if (it.next().ParentId != -10) {
it.remove();
}
}
Il problema è che ogni volta che si rimuove un elemento di copiare (in media) la metà degli elementi rimanenti. Questo perché rimuovere un elemento da un ArrayList
comporta la copia di tutti gli elementi dopo che l'elemento è stato rimosso di una posizione a sinistra.
La soluzione originale che comprende l'elenco di elementi da rimuovere essenzialmente fa la stessa cosa. Sfortunatamente, le proprietà di un ArrayList
non consentono a removeAll
di fare meglio di quanto sopra.
Se si prevede di rimuovere una serie di elementi, il seguente è più efficiente:
ArrayList<DealerProductCount> retain =
new ArrayList<DealerProductCount>(wsResponse.Dealers.size());
for (DealerProductCount dealer : wsResponse.Dealers) {
if (dealer.ParentId == -10) {
retain.add(dealer);
}
}
// either assign 'retain' to 'wsResponse.Dealers' or ...
wsResponse.Dealers.clear();
wsResponse.Dealers.addAll(retain);
Siamo copia (quasi) l'intero elenco due volte, quindi questo dovrebbe andare in pari (in media) se si rimuove solo 4 elementi.
E 'interessante notare che i linguaggi di programmazione funzionali/librerie di supporto tipico di un metodo del filtro, e che può fare questo compito in un solo passaggio attraverso la lista; cioè molto più efficientemente. Penso che possiamo aspettarci miglioramenti significativi se/quando Java supporta lambdas e le API di raccolta sono migliorate per usarle.
fonte
2011-06-08 15:18:57
Esistono altre strutture di dati per le quali la rimozione degli articoli è più efficiente. La rimozione da una LinkedList avrebbe prestazioni O (n). La rimozione da una HashMap avrebbe prestazioni costanti nel tempo. –