É possível transmitir um fluxo no Java 8? Digamos que eu tenha uma lista de objetos, posso fazer algo assim para filtrar todos os objetos adicionais:
Stream.of(objects).filter(c -> c instanceof Client)
Após isso, porém, se eu quiser fazer algo com os clientes, precisarei converter cada um deles:
Stream.of(objects).filter(c -> c instanceof Client)
.map(c -> ((Client) c).getID()).forEach(System.out::println);
Isso parece um pouco feio. É possível converter um fluxo inteiro para um tipo diferente? Como elenco Stream<Object>
para um Stream<Client>
?
Por favor, ignore o fato de que fazer coisas como essa provavelmente significaria um design ruim. Como fazemos coisas na minha aula de ciências da computação, eu estava analisando os novos recursos do java 8 e fiquei curioso para saber se isso era possível.
java
java-8
java-stream
Phiction
fonte
fonte
Respostas:
Eu não acho que exista uma maneira de fazer isso imediatamente. Uma solução possivelmente mais limpa seria:
ou, como sugerido nos comentários, você pode usar o
cast
método - o primeiro pode ser mais fácil de ler:fonte
map
retornaria aStream<Client>
. Obrigado!Stream.of(objects).filter(Client.class::isInstance).[...]
Na linha da resposta de ggovan , faço o seguinte:
Usando esta função auxiliar:
fonte
Tarde para a festa, mas acho que é uma resposta útil.
flatMap
seria a maneira mais curta de fazer isso.Se
o
for umClient
, crie um fluxo com um único elemento, caso contrário, use o fluxo vazio. Esses fluxos serão achatados em aStream<Client>
.fonte
if/else
em vez do?:
operador, não haveria aviso. Tenha certeza de que você pode suprimir com segurança o aviso.Stream.of(objects).filter(o->o instanceof Client).map(o -> (Client)o)
ou uniformeStream.of(objects).filter(Client.class::isInstance).map(Client.class::cast)
.Não, isso não seria possível. Isso não é novo no Java 8. Isso é específico para genéricos. A
List<Object>
não é um super tipo deList<String>
, então você não pode simplesmente converter de aList<Object>
para aList<String>
.Semelhante é o problema aqui. Você não pode lançar
Stream<Object>
paraStream<Client>
. Claro que você pode transmiti-lo indiretamente assim:mas isso não é seguro e pode falhar no tempo de execução. A razão subjacente para isso é que os genéricos em Java são implementados usando apagamento. Portanto, não há informações de tipo disponíveis sobre qual tipo
Stream
está em tempo de execução. Tudo é justoStream
.BTW, o que há de errado com sua abordagem? Parece bom para mim.
fonte
C#
é implementado usando reificação, enquanto que em Java é implementado usando apagamento. Ambos são implementados de maneira diferente subjacente. Portanto, você não pode esperar que funcione da mesma maneira nos dois idiomas.