varios - Eliminar objetos de una ArrayList en Java




recorrer una lista en java (9)

Necesito eliminar algunos objetos de un ArrayList si cumplen una condición y me pregunto qué camino podría ser más eficiente.

Esta es la situación: tengo una clase que contiene una ArrayList contiene algunos otros objetos. Tengo que iterar sobre este ArrayList y eliminar todos los elementos que cumplen una determinada condición. Por lo que sé, esas serían mis opciones para eliminar:

  1. Cree una nueva ArrayList y agregue los elementos que no cumplan con la condición. Después de la iteración, cambie de la lista de arrays anterior a la nueva sin los elementos.

  2. Cree una nueva ArrayList y agregue los elementos que cumplen con la condición. Después de la iteración, use el método removeAll() pasando ArrayList con los objetos que se eliminarán.

¿Hay una forma más eficiente de eliminar objetos de un ArrayList ?


¿Tal vez el método remove() Iterator? Las clases de recopilación predeterminadas de JDK deberían ser todas las iteradoras de creador que admitan este método.


A menos que esté seguro de que el problema al que se enfrenta es, de hecho, un cuello de botella, iría por el texto legible.

public ArrayList filterThings() {

    ArrayList pileOfThings;
    ArrayList filteredPileOfThings = new ArrayList();

    for (Thing thingy : pileOfThings) {
        if (thingy.property != 1) {
            filteredPileOfThings.add(thingy);
        }            
    }
    return filteredPileOfThings;
}

En primer lugar, me aseguraría de que esto realmente sea un cuello de botella de rendimiento; de lo contrario, elegiría la solución más limpia y expresiva.

Si ES un cuello de botella de rendimiento, simplemente pruebe las diferentes estrategias y vea cuál es el más rápido. Mi apuesta es crear una nueva ArrayList y colocar los objetos deseados en esa, descartando la antigua ArrayList.


Estoy bien con la recomendación de Mnementh.
Solo una advertencia,

 ConcurrentModificationException

Tenga en cuenta que no tiene más de un subproceso ejecutándose. Esta excepción podría aparecer si se ejecuta más de un hilo y los hilos no están bien sincronizados.


He encontrado una solución alternativa más rápida:

  int j = 0;
  for (Iterator i = list.listIterator(); i.hasNext(); ) {
    j++;

    if (campo.getNome().equals(key)) {
       i.remove();
       i = list.listIterator(j);
    }
  }

La mayoría de los listIterator , creo, estarían usando el método listIterator y harían una iteración inversa:

for (ListIterator<E> iter = list.listIterator(list.size()); iter.hasPrevious();){
    if (weWantToDelete(iter.previous()))  iter.remove();
}

Editar: Mucho más tarde, uno también podría querer agregar la forma Java 8 de eliminar elementos de una lista (¡o cualquier colección!) Usando una referencia lambda o de método. Un filter in situ para colecciones, si lo desea:

list.removeIf(e -> e.isBad() && e.shouldGoAway());

Esta es probablemente la mejor manera de limpiar una colección. Como utiliza iteración interna, la implementación de la colección podría tomar atajos para hacerlo lo más rápido posible (para ArrayList s, podría minimizar la cantidad de copia necesaria).


Otra forma: The Iterator tiene un método opcional remove (), que se implementa para ArrayList. Puedes usarlo mientras iteras.

No sé, sin embargo, qué variante es la más eficiente, debes medirla.

starblue comentó que la complejidad no es buena, y eso es cierto (para removeAll () también), porque ArrayList tiene que copiar todos los elementos, si en el medio se agrega o elimina un elemento. Para esos casos, una LinkedList debería funcionar mejor. Pero, como no todos conocemos los casos de uso reales, lo mejor es medir todas las variantes para elegir la mejor solución.


Puede repetir hacia atrás y eliminar a medida que avanza en ArrayList. Esto tiene la ventaja de que los elementos posteriores no necesitan desplazarse y es más fácil de programar que avanzar.


int sizepuede= listaoptionVO.size();
for (int i = 0; i < sizepuede; i++) {
    if(listaoptionVO.get(i).getDescripcionRuc()==null){
        listaoptionVO.remove(listaoptionVO.get(i));
        i--;
        sizepuede--;
     }
}

editar: sangría agregada





arraylist