¿Es posible transmitir una secuencia en Java 8?
¿Es posible transmitir una transmisión en Java 8? Digamos que tengo una lista de objetos, puedo hacer algo como esto para filtrar todos los objetos adicionales:
Stream.of(objects).filter(c -> c instanceof Client)
Sin embargo, después de esto, si quiero hacer algo con los clientes, necesitaría emitir cada uno de ellos:
Stream.of(objects).filter(c -> c instanceof Client)
.map(c -> ((Client) c).getID()).forEach(System.out::println);
Esto parece un poco feo. ¿Es posible transmitir una transmisión completa a un tipo diferente? Como arrojado Stream<Object>
a unStream<Client>
?
Ignore el hecho de que hacer cosas como esta probablemente significaría un mal diseño. Hacemos cosas como esta en mi clase de informática, así que estaba investigando las nuevas características de Java 8 y tenía curiosidad por saber si esto era posible.
No creo que haya una manera de hacer eso de manera inmediata. Una solución posiblemente más limpia sería:
Stream.of(objects)
.filter(c -> c instanceof Client)
.map(c -> (Client) c)
.map(Client::getID)
.forEach(System.out::println);
o, como se sugiere en los comentarios, puede utilizar el cast
método; aunque el primero puede ser más fácil de leer:
Stream.of(objects)
.filter(Client.class::isInstance)
.map(Client.class::cast)
.map(Client::getID)
.forEach(System.out::println);
Siguiendo la línea de la respuesta de ggovan , hago esto de la siguiente manera:
/**
* Provides various high-order functions.
*/
public final class F {
/**
* When the returned {@code Function} is passed as an argument to
* {@link Stream#flatMap}, the result is a stream of instances of
* {@code cls}.
*/
public static <E> Function<Object, Stream<E>> instancesOf(Class<E> cls) {
return o -> cls.isInstance(o)
? Stream.of(cls.cast(o))
: Stream.empty();
}
}
Usando esta función auxiliar:
Stream.of(objects).flatMap(F.instancesOf(Client.class))
.map(Client::getId)
.forEach(System.out::println);
Tarde para la fiesta, pero creo que es una respuesta útil.
flatMap
Sería la forma más corta de hacerlo.
Stream.of(objects).flatMap(o->(o instanceof Client)?Stream.of((Client)o):Stream.empty())
Si o
es un Client
, cree una secuencia con un solo elemento; de lo contrario, utilice la secuencia vacía. Estos flujos luego se aplanarán en un formato Stream<Client>
.