Pre-Java 8 debe usar:
tourists.removeAll(Collections.singleton(null));
Uso posterior a Java 8:
tourists.removeIf(Objects::isNull);
La razón aquí es la complejidad del tiempo. El problema con las matrices es que una operación de eliminación puede tardar O (n) en completarse. Realmente en Java, esta es una copia de matriz de los elementos restantes que se mueven para reemplazar el espacio vacío. 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 singleton nulo: entonces O (n)
Debe eliminar All of the singleton, internamente hace un batchRemove () que tiene una posición de lectura y una posición de escritura. E itera la lista. Cuando llega a un valor nulo, simplemente itera la posición de lectura en 1. Cuando son lo mismo que pasa, cuando son diferentes, se sigue moviendo copiando los valores. Luego, al final, se ajusta al tamaño.
Efectivamente hace 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();
}
}
Lo que puede ver explícitamente es una operación O (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 disminuye ese valor. E iterado hasta que los dos valores coinciden. Arruinaría el orden, pero reduciría enormemente la cantidad de valores que establezca frente a los que dejó solo. Es un buen método para saber, pero no ayudará mucho aquí, ya que .set () es básicamente gratuito, pero esa forma de eliminar es una herramienta útil para su cinturón.
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
Si bien esto parece bastante razonable, el .remove () en el iterador llama internamente:
ArrayList.this.remove(lastRet);
Que es nuevamente la operación O (n) dentro de la eliminación. Hace un System.arraycopy () que nuevamente no es lo que quieres, si te importa la velocidad. Esto lo hace n ^ 2.
También hay:
while(tourists.remove(null));
Que 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) operaciones para hacer System.arraycopy () para realizar la eliminación. Literalmente, podría ordenar toda la colección entre elementos con valores y elementos con valores nulos y recortar el final en menos tiempo. De hecho, eso es cierto para todos los rotos. Al menos en teoría, el system.arraycopy real no es en realidad una operación N en la práctica. En teoría, teoría y práctica son lo mismo; en la práctica no lo son.
Iterator
? Excavar java-doc. download.oracle.com/javase/6/docs/api/java/util/…