Est-il possible de diffuser un flux en Java 8? Disons que j'ai une liste d'objets, je peux faire quelque chose comme ceci pour filtrer tous les objets supplémentaires:
Stream.of(objects).filter(c -> c instanceof Client)
Après cela, si je veux faire quelque chose avec les clients, j'aurais besoin de lancer chacun d'eux:
Stream.of(objects).filter(c -> c instanceof Client)
.map(c -> ((Client) c).getID()).forEach(System.out::println);
Cela a l'air un peu moche. Est-il possible de diffuser un flux entier vers un type différent? Comme jeté Stream<Object>
un Stream<Client>
?
Veuillez ignorer le fait que faire de telles choses signifierait probablement une mauvaise conception. Nous faisons des trucs comme ça dans mon cours d'informatique, donc je cherchais les nouvelles fonctionnalités de java 8 et j'étais curieux de savoir si c'était possible.
java
java-8
java-stream
Phiction
la source
la source
Réponses:
Je ne pense pas qu'il y ait un moyen de faire cela hors de la boîte. Une solution éventuellement plus propre serait:
ou, comme suggéré dans les commentaires, vous pouvez utiliser la
cast
méthode - la première peut être plus facile à lire cependant:la source
map
renverrait un fichierStream<Client>
. Merci!Stream.of(objects).filter(Client.class::isInstance).[...]
Le long des lignes de la réponse ggovan , je fais ceci comme suit:
Utilisation de cette fonction d'assistance:
la source
En retard à la fête, mais je pense que c'est une réponse utile.
flatMap
serait le moyen le plus court de le faire.Si
o
est unClient
alors créez un Stream avec un seul élément, sinon utilisez le flux vide. Ces flux seront ensuite aplatis en un fichierStream<Client>
.la source
if/else
plutôt que l'?:
opérateur, il n'y aurait aucun avertissement. Soyez assuré que vous pouvez supprimer l'avertissement en toute sécurité.Stream.of(objects).filter(o->o instanceof Client).map(o -> (Client)o)
ou mêmeStream.of(objects).filter(Client.class::isInstance).map(Client.class::cast)
.Non, ce ne serait pas possible. Ce n'est pas nouveau dans Java 8. Ceci est spécifique aux génériques. A
List<Object>
n'est pas un super type deList<String>
, vous ne pouvez donc pas simplement convertir unList<Object>
en unList<String>
.Le problème est similaire ici. Vous ne pouvez pas lancer
Stream<Object>
versStream<Client>
. Bien sûr, vous pouvez le lancer indirectement comme ceci:mais ce n'est pas sûr et peut échouer à l'exécution. La raison sous-jacente à cela est que les génériques en Java sont implémentés à l'aide de l'effacement. Par conséquent, aucune information de type n'est disponible sur le type de
Stream
celui-ci au moment de l'exécution. Tout est justeStream
.BTW, quel est le problème avec votre approche? Ça me va.
la source
C#
est implémenté à l'aide de la réification, tandis qu'en Java, il est implémenté à l'aide de l'effacement. Les deux sont mis en œuvre de manière différente sous-jacente. Vous ne pouvez donc pas vous attendre à ce que cela fonctionne de la même manière dans les deux langues.