objects - Iterar una enumeración en Java 8
java 8 iterate list of objects (7)
¿Es posible iterar una Enumeration
usando Lambda Expression? Cuál será la representación de Lambda del siguiente fragmento de código:
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
while (nets.hasMoreElements()) {
NetworkInterface networkInterface = nets.nextElement();
}
No encontré ninguna secuencia dentro de ella.
Desde Java-9 habrá un nuevo método predeterminado Enumeration.asIterator()
que simplificará la solución Java pura:
nets.asIterator().forEachRemaining(iface -> { ... });
En caso de que no le guste el hecho de que Collections.list(Enumeration)
copie todo el contenido en una lista (temporal) antes de que comience la iteración, puede ayudarse con un sencillo método de utilidad:
public static <T> void forEachRemaining(Enumeration<T> e, Consumer<? super T> c) {
while(e.hasMoreElements()) c.accept(e.nextElement());
}
Luego puedes hacer simplemente forEachRemaining(enumeration, lambda-expression);
(tenga en cuenta la función import static
) ...
Para Java 8, la transformación más simple de enumeración a transmisión es:
Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
Puede usar la siguiente combinación de funciones estándar:
StreamSupport.stream(Spliterators.spliteratorUnknownSize(CollectionUtils.toIterator(enumeration), Spliterator.IMMUTABLE), parallel)
También puede agregar más características como NONNULL
o DISTINCT
.
Después de aplicar las importaciones estáticas, esto será más legible:
stream(spliteratorUnknownSize(toIterator(enumeration), IMMUTABLE), false)
¡ahora tienes un Stream Java 8 estándar para usar de cualquier forma! Puede pasar true
para procesamiento paralelo.
Para convertir de Enumeration a Iterator use cualquiera de:
-
CollectionUtils.toIterator()
de Spring 3.2 o puede usar -
IteratorUtils.asIterator()
de Apache Commons Collections 3.2 -
Iterators.forEnumeration()
de Google Guava
Sé que esta es una pregunta antigua, pero quería presentar una alternativa a la funcionalidad Collections.asList y Stream. Como la pregunta se titula "Iterar una enumeración", reconozco que a veces se desea usar una expresión lambda, pero un bucle for mejorado puede ser preferible ya que el objeto enumerado puede arrojar una excepción y el bucle for es más fácil de encapsular en una prueba más grande. segmento de código de captura (las lambdas requieren que las excepciones declaradas se capturen dentro de la lambda). Con ese fin, aquí está usando un lambda para crear un Iterable que se puede usar en un ciclo for y no precarga la enumeración:
/**
* Creates lazy Iterable for Enumeration
*
* @param <T> Class being iterated
* @param e Enumeration as base for Iterator
* @return Iterable wrapping Enumeration
*/
public static <T> Iterable<T> enumerationIterable(Enumeration<T> e)
{
return () -> new Iterator<T>()
{
@Override
public T next()
{
return e.nextElement();
}
@Override
public boolean hasNext()
{
return e.hasMoreElements();
}
};
}
Si hay muchas enumeraciones en su código, le recomiendo que cree un método de ayuda estático, que convierta una enumeración en una secuencia . El método estático podría verse de la siguiente manera:
public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
new Iterator<T>() {
public T next() {
return e.nextElement();
}
public boolean hasNext() {
return e.hasMoreElements();
}
},
Spliterator.ORDERED), false);
}
Usa el método con una importación estática . En contraste con la solución de Holger, puede beneficiarse de las diferentes operaciones de flujo , lo que podría hacer que el código existente sea aún más simple. Aquí hay un ejemplo:
Map<...> map = enumerationAsStream(enumeration)
.filter(Objects::nonNull)
.collect(groupingBy(...));
(Esta respuesta muestra una de muchas opciones. El hecho de que haya tenido una marca de aceptación no significa que sea la mejor. Sugiero leer otras respuestas y escoger una según la situación en la que se encuentre. Personalmente para Java 8 encuentro la respuesta de Holger más bonito porque también es simple pero no necesita iteración adicional, lo que sucede en la solución de la mina. Pero para la solución de Java 9, visite la respuesta de Tagir Valeev )
Puede copiar elementos de su Enumeration
a ArrayList
con Collections.list
y luego usarlo como
Collections.list(yourEnumeration).forEach(yourAction);