Pre-Java 8 dovresti usare:
tourists.removeAll(Collections.singleton(null));
Uso di Post-Java 8:
tourists.removeIf(Objects::isNull);
La ragione qui è la complessità temporale. Il problema con le matrici è che un'operazione di rimozione può richiedere il tempo O (n) per il completamento. Davvero in Java questa è una copia dell'array degli elementi rimanenti che vengono spostati per sostituire il punto vuoto. Molte altre soluzioni offerte qui attiveranno questo problema. Il primo è tecnicamente O (n * m) dove m è 1 perché è un singleton null: quindi O (n)
Dovresti rimuovere Tutti i singleton, internamente fa un batchRemove () che ha una posizione di lettura e una posizione di scrittura. E scorre l'elenco. Quando colpisce un valore nullo, itera semplicemente la posizione di lettura di 1. Quando sono gli stessi che passa, quando sono diversi continua a muoversi copiando i valori. Quindi alla fine taglia a misura.
Lo fa efficacemente internamente:
public static <E> void removeNulls(ArrayList<E> list) {
int size = list.size();
int read = 0;
int write = 0;
for (; read < size; read++) {
E element = list.get(read);
if (element == null) continue;
if (read != write) list.set(write, element);
write++;
}
if (write != size) {
list.subList(write, size).clear();
}
}
Che puoi vedere esplicitamente è un'operazione O (n).
L'unica cosa che potrebbe mai essere più veloce è se hai ripetuto l'elenco da entrambe le estremità e quando hai trovato un valore nullo, imposti il suo valore uguale al valore che hai trovato alla fine e decrementa quel valore. E ripetuto fino a quando i due valori corrispondono. Avresti sbagliato l'ordine, ma ridurrai notevolmente il numero di valori impostati rispetto a quelli che hai lasciato da solo. Questo è un buon metodo da sapere, ma qui non sarà di grande aiuto in quanto .set () è sostanzialmente gratuito, ma quella forma di cancellazione è uno strumento utile per la tua cintura.
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
Mentre questo sembra abbastanza ragionevole, il .remove () sull'iteratore chiama internamente:
ArrayList.this.remove(lastRet);
Che è di nuovo l'operazione O (n) all'interno della rimozione. Fa un System.arraycopy () che non è ancora quello che vuoi, se ti interessa la velocità. Questo lo rende n ^ 2.
C'è anche:
while(tourists.remove(null));
Che è O (m * n ^ 2). Qui non solo ripetiamo l'elenco. Ribadiamo l'intero elenco, ogni volta che abbiniamo il null. Quindi eseguiamo n / 2 (media) operazioni per eseguire System.arraycopy () per eseguire la rimozione. Puoi letteralmente ordinare l'intera raccolta tra elementi con valori e elementi con valori null e tagliare la fine in meno tempo. In realtà, questo è vero per tutti quelli rotti. Almeno in teoria, l'attuale system.arraycopy non è in realtà un'operazione N in pratica. In teoria, teoria e pratica sono la stessa cosa; in pratica non lo sono.
Iterator
? Dig java-doc. download.oracle.com/javase/6/docs/api/java/util/…