ArrayList en Java: Recorriendo y eliminando elementos

La clase ArrayList es una de las tantas que implementa la implementa la interfaz List. Por lo tanto es una colección ordenada que puede contener elementos duplicados. A no confundir, cuando digo ordenada me refiero al orden en que se encuentran los elementos dentro de la lista, el cual es independiente a que los elementos se encuentren ordenados por algún criterio, como por ejemplo de menor a mayor.

La clase ArrayList es redimensionable, esto quiere decir que puede crecer o achicarse en tiempo de ejecución, aunque esto es una operación ineficiente cuando se desea insertar o eliminar elementos que se encuentran en el medio, ya que todos los elementos que se encuentran después de este deben ser desplazados. En este caso es mejor usar otras estructuras o clases como LinkedList.

ArrayList comparte muchos comportamientos con la clase Vector y se diferencian en que la primera tiene mejor performance, siempre y cuando no se necesite trabajar con operaciones sincronas.

Pero bueno, basta de tanta introducción. Querían código? Código tendran.

El siguiente ejemplo (Que lo pueden descargar de aqui), Muestra Diferentes formas de recorrer una lista, la antigua forma usando for, con un for mejorado (enhanced for), y usando Iterator. Asi también muestra como eliminar elementos de una lista

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class ArrayListExample {

	public static void main(String[] args){

		String[] bands = {"Nirvana", "Jamiroquai",
                                     "Guns and Roses", "Funkadelic Parliament"};
		List<String> bandList = new ArrayList<String>();

		//add elements from String array to List
		for (String band : bands){
			bandList.add(band);
		}

		String[] undesirableBands = {"Nirvana","Led Zepelling",
                                              "The Strokes", "Jamiroquai"};
		List<String> undesirableList = new ArrayList<String>();

		//add elements from String array to List
		for (String undesirableBand : undesirableBands){
			undesirableList.add(undesirableBand);
		}

		System.out.println("List of bands has: ");
		for (int count = 0; count < bandList.size(); count++){
			System.out.printf("%s ", bandList.get(count));
		}

		removeBands(bandList, undesirableList);
		System.out.println("\n\nI just wish these bands: ");

		for (int count = 0; count < bandList.size(); count++){
			System.out.printf("%s ", bandList.get(count));
		}
	}

	public static void removeBands(Collection<String> bands,
                                         Collection<String> undesirableBands){
		Iterator<String> iteratorBand = bands.iterator();

		while(iteratorBand.hasNext()){
			if(undesirableBands.contains(iteratorBand.next())){
				iteratorBand.remove();
			}
		}
	}
}

 




Empecemos a analizar el código:

 

String[] bands = {"Nirvana", "Jamiroquai",
                       "Guns and Roses", "Funkadelic Parliament"};
		List<String> bandList = new ArrayList<String>();

Primero lo que hacemos es declarar e inicializar un arreglo de String bands que contendra los nombres de las bandas.

Una clase ArrayList es una clase generica y por lo tanto podemos especificarle el tipo de argumento que indican los elementos que la misma contendrá.

Pero, por qué declaramos bandList de tipo List? Simple, esto hace que nuestro código sea mas flexible para modificarlo. Si más tarde desearamos cambiar la implementación a LinkedList podríamos hacerlo solo modificando el lado derecho de la expresión.

Recorrer usando for mejorado

La primera forma de recorrer una lista es esta (Enhanced For Loop):

for (String band : bands){
bandList.add(band);
}

Esta forma de recorrer una lista esta disponible desde la versión Java SE 5.0. Su estructura es simple y permite recorrer todos y cada uno de los elementos de un arreglo/colección (recordar que una Lista es también una colección) en el orden en que se encuentran.

No hay mayores comentarios acerca del método add, este simplemente agrega un elemento a bandList.

De la misma forma se agregan los elementos a la lista undesirableBand. Esta, la vamos a usar para eliminar elementos de la primera

//add elements from String array to List
        for (String undesirableBand : undesirableBands){
            undesirableList.add(undesirableBand);
        }

 

Recorrer usando for clásico

La segunda forma de recorrer una lista es con la ya conocida estructura repetitiva for:

for (int count = 0; count < bandList.size(); count++){
System.out.printf("%s ", bandList.get(count));
}

En este caso, un tanto más engorroso que el primero, usamos métodos propios de la interfaz List. El primero es size() el cual devuelve un número entero con la cantidad de elementos de la lista. El otro método de la interfaz List es get(count) que devuelve el elemento que se encuentra en la posición count.

Recorrer utilizando un Iterador

La tercer forma de recorrer una lista es con un Iterator. La interfaz Iterator permite iterar sobre los elementos de una colección y como mencione anteriormente, una List es un tipo de colección.

El método removeBands(Collection<String> bands, Collection<String> undesirableBands) recibe dos parámetros que pueden ser cualquier tipo de Collections que contengan String. La razon de usar Collection en vez de ArrayList es que le da al método mayor flexibilidad, pudiendo recibir cualquier tipo de objeto que implemente la interfaz Collection.

Tanto la interfaz Collection como Iterator son de tipo genérico.

Analicemos el siguiente fragmento:

Iterator<String> iteratorBand = bands.iterator();

while(iteratorBand.hasNext()){
if(undesirableBands.contains(iteratorBand.next())){
iteratorBand.remove();
}
}

El método iterator() de bands.iterator() devuelve un Iterator de la colección. La interfaz Iterator tiene dos métodos importantes:

  • hasNext(): Este método devuelve true en caso de que existan más elementos
  • next(): Este método nos posiciona en el siguiente elemento del Iterator

El método contains() pregunta si la colección undesirableBands posee el elemento devuelto por iteratorBand.next(), en tal caso lo elimina de iteratorBand con la instrucción iteratorBand.remove()

Para borrar elementos de una colección, la mejor forma es usar Iterator.  Si intentamos hacerlo con el enhanced for obtendremos una excepción de tipo ConcurrentModificationException ya que estamos recorriendo e intentando modificar.

Si una colección es modificada, luego de que se creo el Iterator para la misma, dicho Iterator se vuelve inválido y las operaciones que se quieran realizar sobre el lanzarán excepción de tipo ConcurrentModificationException. Por esto se dice que los iteradores son de fallo rápido

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

doce + diecisiete =