Trato con un lazo como el que

//ArrayList tourists

for (Tourist t : tourists) {
    if (t != null) {     
        t.setId(idForm); 
    }   
}

Pero no es agradable. ¿Alguien puede sugerirme una solución mejor?


Algunos puntos de referencia útiles para hacer la mejor decisión:

Mientras que el bucle, bucle For y Iterador de la Prueba de Rendimiento

InformationsquelleAutor Juan de Dios | 2011-01-27

17 Comentarios

  1. 355

    Tratar:

    tourists.removeAll(Collections.singleton(null));

    Leer el API de Java. El código producirá java.lang.UnsupportedOperationException para inmutable listas (como los creados con Arrays.asList); ver esta respuesta para obtener más detalles.

    • Pequeño detalle de implementación: Esta convocatoria los cambios de la capacidad de Lista.
    • El tiempo de la complejidad de List.removeAll() es n^2. Acaba de decir.
    • Para Java 8 o posterior, consulte @MarcG la respuesta a continuación.
    • ¿Puede explicar cómo se obtuvo que el tiempo de la complejidad? Porque se ve bastante O(n) a mí tanto ArrayList y LinkedList.
    • Creo que no debe ser para este caso, ya que fuente (línea 349) parece un bucle a través de ambas listas (contains() bucles de toda la matriz), y desde el singleton es sólo uno de los elementos sería N * 1 = N. Sin embargo, generalmente, sería N^2.
    • no tiene sentido aquí debido a que el tamaño de ambas colecciones no están relacionados; en última instancia, sería N*M, pero eso no es siempre el caso. ArrayList invalida la definición del método que se ha vinculado a aliviar el costo de hacer múltiples quita, que la convierte en N*T(c.contains); así que si la colección en el parámetro c es un HashSet, será O(N); si es un TreeSet, será O(N*log M). Al mismo tiempo complejidades aplicar para LinkedList, donde ellos no tienen que poner mucho esfuerzo, debido a que elimina son baratos, por definición, si usted tiene la referencia al nodo).
    • No, No es así. Es n*m donde m es el número de elementos en este caso un singleton de null que es 1. Es O(n). Usted puede ver el código fuente aquí y ver que hace leer y escribir sobre la lista de una vez, moviendo los elementos para dar cuenta de la remvoed uno.
    • tenga en cuenta que las Matrices.asList no es inmutable, pero sólo de longitud fija. inmutable significaría también la seguridad de subprocesos, que una lista de tamaño fijo no ofrece.

  2. 112

    A partir de 2015, esta es la mejor manera (Java 8):

    tourists.removeIf(Objects::isNull);

    Nota: Este código producirá java.lang.UnsupportedOperationException de tamaño fijo en las listas (como creado con Matrices.asList), incluyendo inmutable listas.

    • «Mejor» ¿de qué manera? Es más rápido que otros enfoques? O sólo es más fácil de leer por la virtud de la brevedad?
    • No sólo a causa de la brevedad, pero porque es más expresivo. Casi se puede leer: «De los turistas, quitar si el objeto es nulo». También, de la manera antigua es la creación de una nueva colección con un solo objeto nulo, y luego pedir a eliminar el contenido de una colección a partir de la otra. Parece un poco de un hack, ¿no crees? En cuanto a la velocidad, usted tiene un punto, si la lista es muy grande, y el rendimiento es importante, me gustaría sugerir la realización de pruebas de ambas maneras. Mi conjetura sería que removeIf es más rápido, pero es una suposición.
    • Arrays.asList no es inmutable. Es de tamaño fijo.
    • sí, tienes razón, por supuesto. Es de tamaño fijo solo, voy a actualizar la respuesta.
  3. 46
    list.removeAll(Collections.singleton(null));

    Se Lanza UnsupportedException si lo uso en las Matrices.asList porque le Inmutable copia por lo que no puede ser modificado. Vea a continuación el código. Crea Mutable copia y no lanzar ninguna excepción.

    public static String[] clean(final String[] v) {
        List<String> list = new ArrayList<String>(Arrays.asList(v));
        list.removeAll(Collections.singleton(null));
        return list.toArray(new String[list.size()]);
    }
  4. 18

    No es eficiente, pero a corto

    while(tourists.remove(null));
    • Por desgracia, su solución fue el único que trabajó para mí… gracias!
    • simple y rápido
    • el opuesto de rápido, en realidad. terrible lento si tienes una gran lista.
  5. 18

    Si prefieres inmutable de objetos de datos, o si usted no quiere ser destructivo a la lista de entrada, puede utilizar la Guayaba de predicados.

    ImmutableList.copyOf(Iterables.filter(tourists, Predicates.notNull()))
  6. 7
     for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
          if (itr.next() == null) { itr.remove(); }
     }
    • Esto puede ser más útil cuando usted tiene que eliminar los elementos, mientras que atravesar. La coincidencia es que se me fue la anulación de los elementos que intentar usar removeAll(..null..). Gracias!
    • Usted puede ser mejor ajuste de los valores null luego se retira al final. El batchRemove en removeAll atraviesa la lista, con un leer y escribir ubicación y recorre la lista de una vez, moviendo la lectura pero no de escritura cuando se golpea con un null. .remove() puede fiar tienen que arraycopy toda la matriz cada vez que se llama.
  7. 4

    Pre-Java 8 que se debe utilizar:

    tourists.removeAll(Collections.singleton(null));

    Post-Java 8 uso:

    tourists.removeIf(Objects::isNull);

    La razón aquí es el tiempo de la complejidad. El problema con las matrices es que una operación de eliminación puede tomar O(n) tiempo para completar. Realmente en Java esta es una matriz copia de los elementos restantes se trasladó a reemplazar el lugar vacío. Muchas otras soluciones que se ofrecen aquí va a desencadenar este problema. El primero es técnicamente O(n*m) donde m es 1, porque es un singleton null: así que O(n)

    Debe removeAll del singleton, internamente se hace un batchRemove() el cual tiene una lectura de la posición y una posición de escritura. Y se recorre la lista. Cuando se golpea con un null, simplemente repite la lectura de la posición por 1. Cuando son de la misma que pasa, cuando son diferentes se mantiene en movimiento a lo largo de la copia de los valores. Luego, al final se recorta 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();
        }
    }

    Que usted explícitamente pueden ver es una operación O(n).

    La única cosa que nunca podría ser más rápido si es que le reiteró la lista de ambos extremos, y cuando se encuentra un valor null, se establece su valor igual al valor que se encuentra al final, y se reduce a ese valor. Y repite hasta que los dos valores comparados. A usted le desordena el orden, pero reducen enormemente el número de valores
    se establece vs que dejaron solo. Que es un buen método para saber, pero no será de mucha ayuda aquí .set() es básicamente libre, pero que la forma de eliminar es una herramienta útil para el cinturón.


    for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
          if (itr.next() == null) { itr.remove(); }
     }

    Mientras que esto parece bastante razonable, la .remove() en el iterador llama internamente:

    ArrayList.this.remove(lastRet);

    Que es de nuevo la operación O(n) en el quite. Se realiza un Sistema de.arraycopy() que no es otra vez lo que desea, si usted se preocupa acerca de la velocidad. Esto hace que sea n^2.

    También hay:

    while(tourists.remove(null));

    Que es O(m*n^2). Aquí no sólo recorrer la lista. Reiteramos toda la lista, cada vez que coincidir con el valor null. A continuación, hacemos n/2 (promedio) de las operaciones a realizar el Sistema.arraycopy() para realizar la quite.
    Usted puede, literalmente, de ordenación de la colección completa entre los elementos con los valores y los elementos con valores nulos y recortar el final, en menos tiempo. De hecho, eso es cierto para todos los que estén rotos. Al menos en teoría, el sistema real.arraycopy no es en realidad un N funcionamiento 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.

  8. 3

    Hay una manera fácil de eliminar todos los null valores de collection.Usted tiene que pasar una colección que contiene valores null como parámetro para removeAll() método

    List s1=new ArrayList();
    s1.add(null);
    
    yourCollection.removeAll(s1);
    • Esto funciona mejor para mí. También le permite añadir fácilmente más de una entrada en su «matriz de filtro», que se aprobó en el método removeAll de la colección original.
  9. 3

    La Objects clase tiene un nonNull Predicate que puede ser utilizado con filter.

    Por ejemplo:

    tourists.stream().filter(Objects::nonNull).collect(Collectors.toList());
    • Bienvenido a Desbordamiento de Pila. Al responder a las preguntas, por favor, trate de añadir una explicación de su código. Por favor, volver atrás y editar tu respuesta para incluir más información.
  10. 3

    El uso de Java 8, usted puede hacer esto utilizando stream() y filter()

    tourists = tourists.stream().filter(t -> t != null).collect(Collectors.toList())

    o

    tourists = tourists.stream().filter(Objects::nonNull).collect(Collectors.toList())

    Para más info : Java 8 – Corrientes

    • Esta solución es trabajar con Inmutable de la copia que yo.e –> Lista<Cadena> listOfString = Arrays.asList(«prueba1″,null,»prueba»); ….. demasiado ! Gracias
  11. 2

    Esta es la manera fácil de quitar default null valores de arraylist

         tourists.removeAll(Arrays.asList(null));  

    de lo contrario, la Cadena de valor «null» quitar del arraylist

           tourists.removeAll(Arrays.asList("null"));  
  12. 1

    He jugado con este y se encontró que trimToSize() parece que funciona. Estoy trabajando en la plataforma Android, por lo que podría ser diferente.

    • Según el javadoc, trimToSize no modifica el contenido de un ArrayList. Si este es diferente en android, es probable que sea un error.
  13. 1

    Podemos utilizar el iterador de la misma para eliminar todos los valores null.

    Iterator<Tourist> itr= tourists.iterator();
    while(itr.hasNext()){
        if(itr.next() == null){
            itr.remove();
        }
    }
  14. 1

    He utilizado la interfaz de flujo junto con la corriente de operación recoger y un ayudante-método para generar una nueva lista.

    tourists.stream().filter(this::isNotNull).collect(Collectors.toList());
    
    private <T> boolean isNotNull(final T item) {
        return  item != null;
    }
    • tourists.stream().filter(s -> s != null).collect(Collectors.toList());
  15. 0

    Utilizando Java 8 esto se puede realizar de varias maneras usando corrientes, corrientes paralelas y removeIf método:

    List<String> stringList = new ArrayList<>(Arrays.asList(null, "A", "B", null, "C", null));
    List<String> listWithoutNulls1 = stringList.stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList()); //[A,B,C]
    List<String> listWithoutNulls2 = stringList.parallelStream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList()); //[A,B,C]
    stringList.removeIf(Objects::isNull); //[A,B,C]

    La serie paralela hará uso de los procesadores disponibles y acelerar el proceso de razonable tamaño de las listas. Siempre es aconsejable punto de referencia antes de usar los arroyos.

  16. 0

    Similares a @Litio respuesta, pero no lanzar una «Lista no puede contener tipo null» error:

       list.removeAll(Collections.<T>singleton(null));
  17. 0
    List<String> colors = new ArrayList<>(
    Arrays.asList("RED", null, "BLUE", null, "GREEN"));
    //using removeIf() + Objects.isNull()
    colors.removeIf(Objects::isNull);

Dejar respuesta

Please enter your comment!
Please enter your name here