¿Es posible emitir 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é lanzar cada uno de ellos:
Stream.of(objects).filter(c -> c instanceof Client)
.map(c -> ((Client) c).getID()).forEach(System.out::println);
Esto se ve un poco feo. ¿Es posible emitir una transmisión completa a un tipo diferente? ¿Como echar Stream<Object>
a un Stream<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.
java
java-8
java-stream
Ficcion
fuente
fuente
Respuestas:
No creo que haya una manera de hacer eso de forma inmediata. Una solución posiblemente más limpia sería:
o, como se sugiere en los comentarios, podría usar el
cast
método; sin embargo, el primero puede ser más fácil de leer:fuente
map
devolvería aStream<Client>
. ¡Gracias!Stream.of(objects).filter(Client.class::isInstance).[...]
En la línea de la respuesta de ggovan , hago esto de la siguiente manera:
Usando esta función auxiliar:
fuente
Tarde a la fiesta, pero creo que es una respuesta útil.
flatMap
sería la forma más corta de hacerlo.Si
o
es unClient
, cree una secuencia con un solo elemento; de lo contrario, utilice la secuencia vacía. Estas corrientes se aplanarán en aStream<Client>
.fuente
if/else
lugar del?:
operador, no habría advertencia. Tenga la seguridad de que puede suprimir la advertencia de forma segura.Stream.of(objects).filter(o->o instanceof Client).map(o -> (Client)o)
o incluso másStream.of(objects).filter(Client.class::isInstance).map(Client.class::cast)
.No, eso no sería posible. Esto no es nuevo en Java 8. Esto es específico de los genéricos. A
List<Object>
no es un súper tipo deList<String>
, por lo que no puedes simplemente lanzar unList<Object>
a aList<String>
.Similar es el problema aquí. No puedes echar
Stream<Object>
aStream<Client>
. Por supuesto, puedes lanzarlo indirectamente de esta manera:pero eso no es seguro y puede fallar en tiempo de ejecución. La razón subyacente de esto es que los genéricos en Java se implementan mediante borrado. Por lo tanto, no hay información de tipo disponible sobre qué tipo
Stream
está en tiempo de ejecución. Todo es simplementeStream
.Por cierto, ¿qué hay de malo en su enfoque? Luce bien para mi.
fuente
C#
se implementa mediante la reificación, mientras que en Java se implementa mediante el borrado. Ambos se implementan de manera diferente subyacente. Por lo tanto, no puede esperar que funcione de la misma manera en ambos idiomas.