¿Realmente estás tratando de evitar el uso de un iterador, o simplemente no quieres verlo en tu código fuente?
Jon Skeet
2
Puede hacer que el código sea más corto y limpio, pero debe usar un iterador. ¿Hay alguna razón por la que quieras evitarlo?
Peter Lawrey
55
Solo para el registro y como explicación de por qué evitar el iterador: actualmente estoy enfrentando ese problema en un juego de Android escrito en Java. En este momento estoy usando un HashSet para almacenar oyentes que necesitan ser notificados regularmente sobre eventos. Sin embargo, la repetición repetida de las colecciones provoca una gran actividad de recolección de basura que puede cargar el ciclo del juego. Y eso es un no-go en un juego de Java. Voy a reescribir estas partes.
tiguchi
12
@thecoshman Estoy hablando solo desde una perspectiva de desarrollo de juegos Java donde quieres evitar GC durante las actualizaciones regulares del estado del juego a toda costa. Los iteradores son solo objetos útiles temporalmente, ya que no puede restablecerlos al inicio, por lo tanto, se recrean en cada llamada al método de iteración (consulte la fuente ArrayList.java, por ejemplo). Si se usa en un bucle de juego para iterar objetos de escena y considerando al menos 30 actualizaciones por segundo, terminará con al menos 60 objetos iteradores (la escena se repite dos veces por ciclo) por segundo en la memoria en espera de GC. Eso tiene un gran impacto en Android.
tiguchi
9
¿Quizás uno debería elegir una estructura de datos más adecuada en ese caso? Un conjunto no está diseñado para iterar de manera eficiente. ¿Por qué no usar una ArrayList e iterar sobre ella con un bucle estándar? No se crean iteradores adicionales, el acceso de lectura es muy rápido.
@munyengm Sí, lo hace. No hay manera de recorrer un conjunto sin un iterador, además de acceder a la estructura subyacente que contiene los datos a través de la reflexión, y replicar el código proporcionado por Set # iterador ...
assylias
1
Esto funciona, pero si podría dar problemas, entonces no es la solución para mí. Supongo que no tengo elección, debo usar Iterator. Gracias por todo de todos modos.
user1621988
39
@ user1621988 ¿Qué problemas? No hay problemas con el código que proporcioné. Simplemente proporciona una manera agradable y limpia de iterar sobre un conjunto sin tener que usar explícitamente un iterador.
Assylias
90
Hay al menos seis formas adicionales de iterar sobre un conjunto. Los siguientes son conocidos por mí:
Método 1
// Obsolete CollectionEnumeration e =newVector(movies).elements();while(e.hasMoreElements()){System.out.println(e.nextElement());}
Método 2
for(String movie : movies){System.out.println(movie);}
Método 3
String[] movieArray = movies.toArray(newString[movies.size()]);for(int i =0; i < movieArray.length; i++){System.out.println(movieArray[i]);}
Método 4
// Supported in Java 8 and above
movies.stream().forEach((movie)->{System.out.println(movie);});
Método 5
// Supported in Java 8 and above
movies.stream().forEach(movie ->System.out.println(movie));
Método 6
// Supported in Java 8 and above
movies.stream().forEach(System.out::println);
Este es el HashSetque usé para mis ejemplos:
Set<String> movies =newHashSet<>();
movies.add("Avatar");
movies.add("The Lord of the Rings");
movies.add("Titanic");
La declaración for tiene un formulario diseñado para la iteración a través de Colecciones y matrices. A veces se hace referencia a esta forma como la declaración for mejorada, y se puede utilizar para hacer que sus bucles sean más compactos y fáciles de leer.
defaultvoid forEach(Consumer<?super T> action)Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.Unless otherwise specified by the implementing class, actions are performed in the order of iteration (if an iteration order is specified).Exceptions thrown by the action are relayed to the caller.ImplementationRequirements:Thedefault implementation behaves as if:for(T t :this)
action.accept(t);Parameters: action -The action to be performed for each elementThrows:NullPointerException-if the specified action is nullSince:1.8
Sin embargo, hay muy buenas respuestas ya disponibles para esto. Aquí está mi respuesta:
1. set.stream().forEach(System.out::println);// It simply uses stream to display set values2. set.forEach(System.out::println);// It uses Enhanced forEach to display set values
Además, si este conjunto es de tipo de clase personalizada, por ejemplo: Cliente.
Respuestas:
Puede usar un bucle for mejorado :
O con Java 8:
fuente
Hay al menos seis formas adicionales de iterar sobre un conjunto. Los siguientes son conocidos por mí:
Método 1
Método 2
Método 3
Método 4
Método 5
Método 6
Este es el
HashSet
que usé para mis ejemplos:fuente
stream()
.La conversión de su conjunto en una matriz también puede ayudarlo a iterar sobre los elementos:
fuente
toArray
llama al iterador del conjunto.Para demostrarlo, considere el siguiente conjunto, que contiene diferentes objetos Persona:
fuente
Puede usar la operación funcional para un código más ordenado
fuente
Aquí hay algunos consejos sobre cómo iterar un set junto con sus actuaciones:
El código se explica por sí mismo.
El resultado de las duraciones son:
Podemos ver las
Lambda
tomas más largas mientrasIterator
que las más rápidas.fuente
Enumeración(?):
Otra forma (java.util.Collections.enumeration ()):
Java 8:
o
fuente
Sin embargo, hay muy buenas respuestas ya disponibles para esto. Aquí está mi respuesta:
Además, si este conjunto es de tipo de clase personalizada, por ejemplo: Cliente.
// Clase de cliente:
fuente