In termini pratici, LinkedList#removeFirst
è più efficiente poiché funziona su una lista doppiamente collegata e la rimozione del primo elemento consiste essenzialmente nel solo scollegarlo dal capo dell'elenco e aggiornare l'elemento successivo in modo che sia il primo:
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
ArrayList#remove
sta operando su una matrice interna che richiede shiftting tutti subsequents elementi di una posizione a sinistra copiando il subarray:
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
altra hand, LinkedList#get
operazione richiede attraversando la metà dell'intero elenco per il recupero di un elemento in un indice specificato - nel peggiore dei casi. ArrayList#get
accede direttamente all'elemento all'indice specificato poiché opera su un array.
La mia regola di pollice per l'efficienza qui sarebbe:
- Usa
LinkedList
se si fa un sacco di add
/remove
in confronto con operazioni di recupero (ad es .: get
);
- Utilizzare
ArrayList
se si esegue un lotto di operazioni di recupero rispetto a add
/remove
.
a) definisce le prestazioni. Ci sono molte variabili da misurare, come il tempo, l'efficienza, l'uso della memoria, ecc. B) Scrivi del codice di prova, usando cronometri (di classe, non fisici) e cose di quella natura per confrontarlo e scoprirlo. –
"Qual è il modo più efficiente per farlo?" Dipende dal tuo scenario. Vedi http://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist – Shar1er80