Pre-8 de Java que puedes usar:
tourists.removeAll(Collections.singleton(null));
Post-Java 8 uso:
tourists.removeIf(Objects::isNull);
La razón aquí es la complejidad de tiempo. El problema con las matrices es que una operación de eliminación puede tomar O (n) tiempo para completarse. Realmente en Java, esta es una copia de la matriz de los elementos restantes que se mueven para reemplazar la mancha vacía. Muchas otras soluciones que se ofrecen aquí desencadenarán este problema. El primero es técnicamente O (n * m) donde m es 1 porque es un nulo singleton: así que O (n)
Debe eliminar Todo del singleton, internamente hace un batchRemove() que tiene una posición de lectura y una escribir posición Y repite la lista. Cuando llega a un nulo, simplemente itera la posición de lectura en 1. Cuando pasan lo mismo, cuando son diferentes se mueve a lo largo de la copia de los valores. Luego, al final, se ajusta a medida.
Lo hace efectivamente esto 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();
}
}
que se puede ver de forma explícita es un O (n) la operación.
Lo único que podría ser más rápido es si itera la lista desde ambos extremos, y cuando encuentra un valor nulo, establece su valor igual al valor que encontró al final y decrementa ese valor. Y se repitió hasta que los dos valores coincidieron. Desordenarías el orden, pero reducirías enormemente el número de valores que estableces frente a los que dejaste solos. Lo cual es un buen método para saber pero no ayudará mucho porque .set() es básicamente gratis, pero esa forma de eliminar es una herramienta útil para tu cinturón.
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
Si bien esto parece bastante razonable, el .Remove() del iterador llama internamente:
ArrayList.this.remove(lastRet);
que es otra vez la operación O (n) dentro de la eliminación. Hace una System.arraycopy() que de nuevo no es lo que quieres, si te importa la velocidad. Esto lo hace n^2.
Hay también:
while(tourists.remove(null));
Qué es O (m * n^2). Aquí no solo iteramos la lista. Reiteramos toda la lista, cada vez que hacemos coincidir el nulo. Luego hacemos n/2 (promedio) de operaciones para hacer el System.arraycopy() para realizar la eliminación. Podría literalmente clasificar la colección completa entre elementos con valores y elementos con valores nulos y recortar la terminación en menos tiempo. De hecho, eso es cierto para todos los rotos. Al menos en teoría, el sistema real.arraycopy no es realmente una operación N en la práctica. En teoría, la teoría y la práctica son la misma cosa; en la práctica, no lo son.
uso 'Iterator'? Dig java-doc. http://download.oracle.com/javase/6/docs/api/java/util/Iterator.html#remove%28%29 – Nishant