2012-09-17 32 views
186

¿Cómo puedo iterar sobre Set/HashSet sin lo siguiente?¿Cómo puedo iterar sobre un conjunto/HashSet sin un iterador?

Iterator iter = set.iterator(); 
while (iter.hasNext()) { 
    System.out.println(iter.next()); 
} 
+25

¿En realidad tratando de evitar el uso de un repetidor, o sólo no quieren ver en su código fuente * *? –

+1

Puede hacer que el código sea más corto y más limpio, pero debe usar un iterador. ¿Hay alguna razón por la que quieres evitarlo? –

+2

¿Cuál es su razón para querer evitar las estructuras proporcionadas en el idioma para el propósito que desea lograr? – EJP

Respuesta

369

Puede utilizar un enhanced for loop:

Set<String> set = new HashSet<String>(); 

//populate set 

for (String s : set) { 
    System.out.println(s); 
} 

O con Java 8:

set.forEach(System.out::println); 
+52

Creo que esto usa un iterador detrás de las escenas. – munyengm

+14

@munyengm Sí lo hace. No hay forma de iterar sobre 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 provisto por Set # iterator ... – assylias

+1

Esto funciona, pero si puede dar problemas, entonces es no es la solución para mí Supongo que no tengo elección, debo usar Iterator. Gracias por todos de todos modos. – user1621988

17

La conversión de su conjunto en una matriz también le puede ayudar para iterar sobre los elementos :

Object[] array = set.toArray(); 

for(int i=0; i<array.length; i++) 
    Object o = array[i]; 
+40

Solo para el registro, 'toArray' llama al iterador del conjunto. – assylias

+0

@assylias tiene razón :( – Juvanis

1

Enumeración (?):

Enumeration e = new Vector(set).elements(); 
while (e.hasMoreElements()) 
    { 
     System.out.println(e.nextElement()); 
    } 

Otra forma (java.util.Collections.enumeration()):

for (Enumeration e1 = Collections.enumeration(set); e1.hasMoreElements();) 
    { 
     System.out.println(e1.nextElement()); 
    } 

Java 8:

set.forEach(element -> System.out.println(element)); 

o

10

Para demostrarlo, consideremos el siguiente conjunto, que tiene diferentes objetos Persona:

Set<Person> people = new HashSet<Person>(); 
people.add(new Person("Tharindu", 10)); 
people.add(new Person("Martin", 20)); 
people.add(new Person("Fowler", 30)); 

persona modelo de clase

public class Person { 
    private String name; 
    private int age; 

    public Person(String name, int age) { 
     this.name = name; 
     this.age = age; 
    } 

    //TODO - getters,setters ,overridden toString & compareTo methods 

} 
  1. La sentencia tiene una forma diseñada para la iteración a través de colecciones y arrays. Este formulario a veces se denomina declaración mejorada para, y se puede usar para hacer que sus loops sean más compactos y fáciles de leer.
for(Person p:people){ 
    System.out.println(p.getName()); 
} 
  1. Java 8 - java.lang.Iterable.forEach (Consumidor)
people.forEach(p -> System.out.println(p.getName())); 
default void 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. Implementation Requirements: 

The default implementation behaves as if: 

for (T t : this) 
    action.accept(t); 

Parameters: action - The action to be performed for each element 

Throws: NullPointerException - if the specified action is null 

Since: 1.8 
45

Hay al menos seis formas adicionales de iterar sobre un conjunto.se sabe que me La siguiente:

Método 1

// Obsolete Collection 
Enumeration e = new Vector(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(new String[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 HashSet que utilicé para mis ejemplos:

Set<String> movies = new HashSet<>(); 
movies.add("Avatar"); 
movies.add("The Lord of the Rings"); 
movies.add("Titanic"); 
+1

Hi @ benny-neugebauer Para ** Método 4 **, ** Método 5 **, ** Método 6 ** simplemente puede eliminar redundante 'stream()'. –

1

Éstos son algunos consejos sobre la manera de recorrer un conjunto junto con sus actuaciones:

public class IterateSet { 

    public static void main(String[] args) { 

     //example Set 
     Set<String> set = new HashSet<>(); 

     set.add("Jack"); 
     set.add("John"); 
     set.add("Joe"); 
     set.add("Josh"); 

     long startTime = System.nanoTime(); 
     long endTime = System.nanoTime(); 

     //using iterator 
     System.out.println("Using Iterator"); 
     startTime = System.nanoTime(); 
     Iterator<String> setIterator = set.iterator(); 
     while(setIterator.hasNext()){ 
      System.out.println(setIterator.next()); 
     } 
     endTime = System.nanoTime(); 
     long durationIterator = (endTime - startTime); 


     //using lambda 
     System.out.println("Using Lambda"); 
     startTime = System.nanoTime(); 
     set.forEach((s) -> System.out.println(s)); 
     endTime = System.nanoTime(); 
     long durationLambda = (endTime - startTime); 


     //using Stream API 
     System.out.println("Using Stream API"); 
     startTime = System.nanoTime(); 
     set.stream().forEach((s) -> System.out.println(s)); 
     endTime = System.nanoTime(); 
     long durationStreamAPI = (endTime - startTime); 


     //using Split Iterator (not recommended) 
     System.out.println("Using Split Iterator"); 
     startTime = System.nanoTime(); 
     Spliterator<String> splitIterator = set.spliterator(); 
     splitIterator.forEachRemaining((s) -> System.out.println(s)); 
     endTime = System.nanoTime(); 
     long durationSplitIterator = (endTime - startTime); 


     //time calculations 
     System.out.println("Iterator Duration:" + durationIterator); 
     System.out.println("Lamda Duration:" + durationLambda); 
     System.out.println("Stream API:" + durationStreamAPI); 
     System.out.println("Split Iterator:"+ durationSplitIterator); 
    } 
} 

El código se explica por sí mismo.

El resultado de las duraciones son:

Iterator Duration:495287 
Lamda Duration:50207470 
Stream API:2427392 
Split Iterator:567294 

Podemos ver la Lambda toma más tiempo, mientras que Iterator es el más rápido.

1

Puede usar la operación funcional de un código más limpio

Set<String> set = new HashSet<String>(); 

set.forEach((s) -> { 
    System.out.println(s); 
}); 
Cuestiones relacionadas