Iteradores

Iteradores

En Java, los iteradores son objetos que permiten recorrer colecciones de manera secuencial. Las interfaces Iterator y ListIterator proporcionan métodos para acceder, modificar y eliminar elementos de colecciones. Estos iteradores se utilizan especialmente cuando necesitas recorrer elementos sin exponer la estructura interna de la colección. A continuación, te explico en detalle qué son y cómo se utilizan los iteradores, junto con sus interfaces específicas.

Resumen de diferencias entre Iterator y ListIterator:

Característica Iterator ListIterator
Dirección de iteración Solo hacia adelante Hacia adelante y hacia atrás
Métodos adicionales No tiene hasPrevious(), previous(), add(), set()
Modificación de elementos Solo puede eliminar elementos Puede eliminar, agregar y modificar elementos
Usabilidad Usado con cualquier Collection Usado exclusivamente con listas (List)
Eficiencia Generalmente eficiente en la mayoría de colecciones Más eficiente para las operaciones en listas, ya que permite moverse hacia atrás

1. Iterator

La interfaz Iterator proporciona los métodos básicos para recorrer colecciones de tipo Collection (como List, Set, etc.) de manera secuencial.

Métodos de Iterator:

  1. hasNext():
    • Descripción: Devuelve true si la colección tiene más elementos para iterar, de lo contrario devuelve false.
    • Uso: Se utiliza típicamente en bucles while para verificar si hay más elementos disponibles.
  2. next():
    • Descripción: Devuelve el siguiente elemento de la colección y avanza el puntero del iterador. Si no hay más elementos, lanza NoSuchElementException.
    • Uso: Se utiliza para obtener el siguiente elemento en la colección.
  3. remove():
    • Descripción: Elimina el último elemento que fue retornado por next(). Lanza IllegalStateException si no se ha llamado a next() antes de remove() o si ya se ha llamado a remove() después de la última llamada a next().
    • Uso: Se utiliza para eliminar el último elemento accedido durante la iteración.

Ejemplo de uso de Iterator:

import java.util.*;

public class IteratorExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Python");
        list.add("JavaScript");

        // Crear un iterador para recorrer la lista
        Iterator<String> iterator = list.iterator();

        // Iterar a través de la colección
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);  // Imprime los elementos de la lista
        }

        // Eliminar un elemento usando el iterador
        iterator = list.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            if (element.equals("Python")) {
                iterator.remove();  // Elimina "Python" de la lista
            }
        }

        System.out.println(list);  // Imprime la lista sin "Python"
    }
}

Salida:

Java
Python
JavaScript
[Java, JavaScript]

En el ejemplo, se usa iterator.remove() para eliminar el elemento "Python" de la lista mientras se recorre con el iterador.


2. ListIterator

ListIterator es una extensión de Iterator que permite recorrer listas en ambas direcciones: hacia adelante y hacia atrás. Además, proporciona más funcionalidades, como modificar los elementos mientras se itera.

Métodos adicionales de ListIterator:

  1. hasPrevious():
    • Descripción: Devuelve true si hay elementos previos en la lista, de lo contrario devuelve false.
    • Uso: Se utiliza para verificar si se puede retroceder en la lista.
  2. previous():
    • Descripción: Devuelve el elemento anterior en la lista y mueve el puntero hacia atrás. Lanza NoSuchElementException si no hay elementos previos.
    • Uso: Se utiliza para acceder al elemento anterior durante la iteración en reversa.
  3. add(E e):
    • Descripción: Inserta el elemento especificado en la lista en la posición actual del iterador.
    • Uso: Se utiliza para agregar un nuevo elemento en el lugar en que se encuentra el iterador.
  4. set(E e):
    • Descripción: Reemplaza el último elemento que fue retornado por next() o previous() con el elemento especificado.
    • Uso: Se utiliza para modificar el elemento que el iterador ha visitado.

Ejemplo de uso de ListIterator:

import java.util.*;

public class ListIteratorExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Python");
        list.add("JavaScript");

        // Crear un ListIterator para recorrer la lista
        ListIterator<String> listIterator = list.listIterator();

        // Iterar hacia adelante
        System.out.println("Iterando hacia adelante:");
        while (listIterator.hasNext()) {
            String element = listIterator.next();
            System.out.println(element);  // Imprime los elementos de la lista
        }

        // Modificar un elemento con set()
        listIterator = list.listIterator();  // Reiniciamos el iterador
        while (listIterator.hasNext()) {
            String element = listIterator.next();
            if (element.equals("Python")) {
                listIterator.set("Ruby");  // Cambia "Python" a "Ruby"
            }
        }

        // Iterar hacia atrás
        System.out.println("\nIterando hacia atrás:");
        while (listIterator.hasPrevious()) {
            String element = listIterator.previous();
            System.out.println(element);  // Imprime los elementos de la lista en reversa
        }

        // Agregar un elemento
        listIterator.add("Go");
        System.out.println("\nLista final: " + list);
    }
}

Salida:

Iterando hacia adelante:
Java
Python
JavaScript

Iterando hacia atrás:
JavaScript
Ruby
Java

Lista final: [Java, Ruby, JavaScript, Go]

En este ejemplo, utilizamos ListIterator para recorrer la lista de adelante hacia atrás, modificar el valor de "Python" a "Ruby" y agregar el elemento "Go" al final de la lista.