recorrer obtener listas linkedlist imprimir español elemento ejemplo java collections iterator

obtener - recorrer arraylist java foreach



Iterador de Java sobre una colección vacía de un tipo parametrizado (7)

En Java, necesito devolver un iterador desde mi método. Mis datos provienen de otro objeto que generalmente me puede dar un iterador, así que simplemente puedo devolverlo, pero en algunas circunstancias los datos subyacentes son nulos. Por coherencia, quiero devolver un iterador "vacío" en ese caso para que las personas que llaman no tengan que probar el valor nulo.

Quería escribir algo como:

public Iterator<Foo> iterator() { if (underlyingData != null) { return underlyingData.iterator(); // works } else { return Collections.emptyList().iterator(); // compiler error } }

Pero el compilador de Java se queja sobre el regreso del Iterator<Object> lugar del Iterator<Foo> . La conversión a (Iterator<Foo>) tampoco funciona.


Java 7 ha estado fuera por mucho tiempo. A menos que esté desarrollando para una versión anterior de Java, devolvería un iterador vacío como este:

return Collections.emptyIterator();


La molestia de las Collections.<Foo>emptyList().iterator() es la razón principal por la que proporcionamos Iterators.emptyIterator() en google-collections . No necesita ningún tipo de parámetro, en casos como el suyo.


Lo siento, lo descubrí. Debe utilizar una asignación para que el compilador pueda averiguar el tipo parametrizado.

public Iterator<Foo> iterator() { if (underlyingData != null) { return underlyingData.iterator(); } else { List<Foo> empty = Collections.emptyList(); // param type inference return empty.iterator(); } }


Puede obtener una lista vacía de tipo Foo a través de la siguiente sintaxis:

return Collections.<Foo>emptyList().iterator();


Supongo que esto muestra que la inferencia de tipos de Java no funciona en todos los casos y que el operador ternario no siempre es equivalente al constructo aparentemente equivalente if-else.

También quiero decir " Evitar null . También evite pasar Iterator s, porque tienen un comportamiento extraño con estado (prefiera Iterable ). Sin embargo, suponiendo que tenga una razón legítima y no prematura para hacer esto, mi forma preferida de escribirlo sería

public Iterator<Foo> iterator() { return getUnderlyingData().iterator(); } private List<Foo> getUnderlyingData() { if (underlyingData == null) { return Collections.emptyList(); } else { return underlyingData; } }

En mi opinión, es mejor no insertar la información de tipo inferable si se puede inferir (incluso si hace que su código sea más largo).

Es casi seguro que lo hará más de una vez, así que inserte un método getUnderlyingData lugar de declarar una variable local.

Está llamando iterator en ambos resultados, así que no se repita.


Yo iría más en la línea de

public Iterator<Foo> iterator() { if (underlyingData == null) return Collections.<Foo> emptyList().iterator(); return underlyingData.iterator(); }

Simplemente, maneja el estuche especial y regresa, luego maneja el estuche normal. Pero mi punto principal es que puedes evitar la asignación con

Collections.<Foo> emptyList().iterator();


public final class EmptyIterator{ public static Iterator iterator(){ return new Empty(); } private static class Empty implements Iterator { public boolean hasNext(){ return false; } public Object next(){ throw new NoSuchElementException(); } public void remove(){ } } }