1. Antecedentes sobre cómo surgieron los iteradores

Ya estás familiarizado con HashSet. Si realmente lo investigaste, más allá de solo leer una lección, entonces deberías haberte hecho esta pregunta:

¿Cómo muestro una lista de todos los elementos HashSet en la pantalla? ¡Después de todo, la interfaz no tiene get()métodos set()!

Y HashSetno está solo en esta limitación. Además de HashSet, hay muchas otras colecciones que no permiten recuperar elementos por índice, porque los elementos no tienen un orden definido.

A lo largo de los años, los programadores han inventado muchas estructuras de datos complejas, como gráficos y árboles. O listas de listas.

Muchos contenedores cambian el orden de sus elementos cuando se agregan elementos nuevos o se eliminan elementos existentes. Por ejemplo, una lista almacena elementos en un orden particular y cuando se agrega un nuevo elemento, casi siempre se inserta en el medio de la lista.

Y también tenemos situaciones en las que hay un contenedor que almacena elementos pero no en un orden fijo.

Ahora digamos que queremos copiar todos los elementos de dicha colección en una matriz o lista. Necesitamos conseguir todos los elementos. No nos importa el orden en el que iteramos sobre los elementos; lo importante es no iterar sobre los mismos elementos más de una vez. ¿Como hacemos eso?


2. Iterador para una colección

Se propusieron iteradores como una solución al problema anterior.

Un iterador es un objeto especial asociado con una colección, que ayuda a recorrer todos los elementos de la colección sin repetir ninguno.

Puede usar el siguiente código para obtener un iterador para cualquier colección:

Iterator<Type> it = name.iterator();

Donde namees el nombre de la variable de colección, Typees el tipo de los elementos de la colección, iterator()es uno de los métodos de la colección y ites el nombre de la variable iteradora.

Un objeto iterador tiene 3 métodos:

Método Descripción
Type next()
Devuelve el siguiente elemento de la colección.
boolean hasNext()
Comprueba si hay elementos que aún no se han recorrido
void remove()
Elimina el elemento actual de la colección.

nextInt)Estos métodos son algo similares a los métodos y de la clase Scanner hasNextInt().

El next()método devuelve el siguiente elemento de la colección de la que obtuvimos el iterador.

El hasNext()método verifica si la colección tiene elementos adicionales que el iterador aún no ha devuelto.

A continuación se explica cómo mostrar todos los elementos de un HashSet:

Código notas
HashSet<String> set = new HashSet<String>();

set.add("Hallo");
set.add("Hello");
set.add("Hola");
set.add("Bonjour");
set.add("Ciao");
set.add("Namaste");

Iterator<String> it = set.iterator();
while (it.hasNext())
{
   String str = it.next();
   System.out.println(str);
}
Cree un HashSetobjeto que almacene Stringelementos.


Agregamos saludos en varios idiomas a la setvariable.




Obtenga un objeto iterador para el setconjunto.
Mientras haya elementos

Obtener el siguiente elemento
Mostrar el elemento en la pantalla

10
Tarea
Módulo 1. Java Syntax,  nivel 27lección 0
Bloqueada
No solo el lunes :)
task1601

3. For-eachbucle

La principal desventaja de un iterador es que su código se vuelve más engorroso que usar un forbucle.

Para comparar, mostremos una lista usando un forbucle y también usando un iterador:

iterador en bucle
ArrayList<String> list = new ArrayList<String>();

Iterator<String> it = list.iterator();
while (it.hasNext())
{
   String str = it.next();
   System.out.println(str);
}
ArrayList<String> list = new ArrayList<String>();

for (int i = 0; i < list.size(); i++)
{
   String str = list.get(i);
   System.out.println(str);
}

Sí, es mucho mejor atravesar los elementos de un ArrayListbucle usando un bucle: todo resulta ser más corto.

Pero los creadores de Java nuevamente decidieron echarnos un poco de azúcar. Por suerte para nosotros, era azúcar sintáctico .

Le dieron a Java un nuevo tipo de bucle y lo llamaron for-eachbucle. Así es como se ve en general:

for(Type name:collection)

Donde collectiones el nombre de la variable de la colección, Typees el tipo de los elementos de la colección y namees el nombre de una variable que toma el siguiente valor de la colección en cada iteración del ciclo.

Este tipo de bucle recorre en iteración todos los elementos de una colección mediante un iterador implícito. Así es como funciona en realidad:

Bucle para cada uno Lo que ve el compilador: Bucle con un iterador
ArrayList<String> list = new ArrayList<String>();

for (String str: list)
{
   System.out.println(str);
}
ArrayList<String> list = new ArrayList<String>();
Iterator<String> it = list.iterator();

while (it.hasNext())
{
   String str = it.next();
   System.out.println(str);
}

Cuando el compilador encuentra un for-eachbucle en su código, simplemente lo reemplaza con el código de la derecha: agrega una llamada para obtener un iterador junto con cualquier otra llamada de método faltante.

A los programadores les encanta el for-eachbucle y casi siempre lo usan cuando necesitan iterar sobre todos los elementos de una colección.

Incluso iterar sobre una ArrayListlista usando un for-eachbucle parece más corto:

Bucle para cada uno en bucle
ArrayList<String> list = new ArrayList<String>();

for (String str: list)
{
   System.out.println(str);
}
ArrayList<String> list = new ArrayList<String>();

for (int i = 0; i < list.size(); i++)
{
   String str = list.get(i);
   System.out.println(str);
}

10
Tarea
Módulo 1. Java Syntax,  nivel 27lección 0
Bloqueada
Para limpiar pendientes
task1602

4. Eliminar un elemento en un for-eachbucle

El for-eachbucle tiene un inconveniente: no puede eliminar elementos correctamente. Si escribe un código como este, obtendrá un error.

Código Nota
ArrayList<String> list = new ArrayList<String>();

list.add("Hallo");
list.add("Hello");
list.add("Hola");
list.add("Bonjour");
list.add("Ciao");
list.add("Namaste");

for (String str: list)
{
   if (str.equals("Hello"))
      list.remove(str);
}












¡La operación de eliminación generará un error!

Este es un código muy agradable y comprensible, pero no funcionará.

¡Importante!

No puede cambiar una colección mientras la recorre con un iterador.

Hay tres formas de sortear esta limitación.

1. Usa un tipo diferente de bucle

When traversing an ArrayList collection, puede usar un ciclo ordinario con una ivariable de contador.

Código
for (int i = 0; i < list.size(); i++)
{
   String str = list.get(i);

   if (str.equals("Hello"))
   {
      list.remove(str);
      i--; // We need to decrease i, because the remove operation shifted the elements
   }
}

Sin embargo, esta opción no es adecuada para HashSety HashMapcolecciones

2. Usa un iterador explícito

Puede usar un iterador explícitamente y llamar a su remove()método.

Versión que funciona Versión que no funciona
Iterator<String> it = set.iterator();
while (it.hasNext())
{
   String str = it.next();
   if (str.equals("Hello"))
       it.remove();
}
for (String str: list)
{
   if (str.equals("Hello"))
      list.remove(str);
}

¡ Tenga en cuenta que llamamos al remove()método en el objeto iterador! El iterador es consciente de que el elemento se ha eliminado y puede manejar la situación correctamente.

3. Usa una copia de la colección

También puede crear una copia de la colección y luego usar la copia en un for-eachbucle y eliminar elementos de la colección original.

Código Nota
ArrayList<String> listCopy = new ArrayList(list);

for (String str: listCopy)
{
   if (str.equals("Hello"))
      list.remove(str);
}
Crear una copia de una colección es muy fácil.



El ciclo usa el iterador para la copia de la colección.
Los elementos se eliminan de la listcolección.

La colección se copia con bastante rapidez, ya que los elementos en sí no se duplican. En cambio, la nueva colección almacena referencias a los elementos que ya existen en la colección anterior.

10
Tarea
Módulo 1. Java Syntax,  nivel 27lección 0
Bloqueada
Arreglar el formato
task1603