Przed wersją Java 8 powinieneś używać:
tourists.removeAll(Collections.singleton(null));
Użycie po wersji Java 8:
tourists.removeIf(Objects::isNull);
Powodem jest złożoność czasu. Problem z tablicami polega na tym, że operacja usunięcia może zająć O (n) czasu. Naprawdę w Javie jest to tablica kopii pozostałych elementów przenoszonych w celu zastąpienia pustego miejsca. Wiele innych rozwiązań tutaj oferowanych spowoduje ten problem. Ten pierwszy jest technicznie O (n * m), gdzie m wynosi 1, ponieważ jest singletonem zerowym: więc O (n)
Powinieneś usunąćAll z singletonu, wewnętrznie robi on batchRemove (), który ma pozycję odczytu i pozycję zapisu. I iteruje listę. Kiedy osiągnie wartość zerową, po prostu iteruje pozycję odczytu o 1. Gdy są one takie same, mija, kiedy są różne, przesuwa się dalej, kopiując wartości. Następnie na końcu przycina się do rozmiaru.
Skutecznie robi to wewnętrznie:
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();
}
}
To, co wyraźnie widać, to operacja O (n).
Jedyną rzeczą, która mogłaby być szybsza, jest iteracja listy z obu końców, a po znalezieniu wartości null ustawia się jej wartość równą wartości znalezionej na końcu i zmniejsza tę wartość. I iterował, aż obie wartości się zgadzały. Zepsujesz porządek, ale znacznie zmniejszysz liczbę ustawionych wartości w porównaniu z wartościami, które pozostawiłeś sam. Co jest dobrą metodą na poznanie, ale tutaj niewiele pomoże, ponieważ .set () jest w zasadzie darmowy, ale ta forma usuwania jest przydatnym narzędziem dla twojego paska.
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
Chociaż wydaje się to rozsądne, funkcja .remove () iteratora wywołuje wewnętrznie:
ArrayList.this.remove(lastRet);
To znowu operacja O (n) w usuwaniu. Robi System.arraycopy (), który znowu nie jest tym, czego chcesz, jeśli zależy ci na szybkości. To sprawia, że n ^ 2.
Jest także:
while(tourists.remove(null));
Który jest O (m * n ^ 2). Tutaj nie tylko iterujemy listę. Powtarzamy całą listę za każdym razem, gdy dopasowujemy zero. Następnie wykonujemy n / 2 (przeciętne) operacje, aby wykonać System.arraycopy () w celu wykonania operacji usuwania. Można dosłownie posortować całą kolekcję między elementami o wartościach i elementami o wartościach zerowych i przyciąć zakończenie w krótszym czasie. W rzeczywistości dotyczy to wszystkich zepsutych. Przynajmniej teoretycznie faktyczny system. Arraycopy nie jest w rzeczywistości operacją N. Teoretycznie teoria i praktyka są tym samym; w praktyce nie są.
Iterator
? Dig java-doc. download.oracle.com/javase/6/docs/api/java/util/…