是否有可能在Java 8中投射stream?

是否有可能在Java 8中投射stream? 说我有一个对象列表,我可以做这样的事情来过滤掉所有的附加对象:

Stream.of(objects).filter(c -> c instanceof Client) 

在这之后,如果我想和客户做一些事情,我需要把它们中的每一个都投给:

 Stream.of(objects).filter(c -> c instanceof Client) .map(c -> ((Client) c).getID()).forEach(System.out::println); 

这看起来有点难看。 是否有可能将整个stream转换为不同的types? 像将Stream<Object> Stream<Client>转换为Stream<Client>

请忽略这样的事实可能意味着不好的devise。 我们在计算机科学课上做这样的东西,所以我正在研究java 8的新特性,并且很好奇这是否可能。

我不认为有一种方法可以做到这一点。 一个可能更干净的解决scheme是:

 Stream.of(objects) .filter(c -> c instanceof Client) .map(c -> (Client) c) .map(Client::getID) .forEach(System.out::println); 

或者如注释中所build议的那样,您可以使用cast方法 – 前者可能更容易阅读:

 Stream.of(objects) .filter(Client.class::isInstance) .map(Client.class::cast) .map(Client::getID) .forEach(System.out::println); 

根据ggovan的回答 ,我这样做如下:

 /** * 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(); } } 

使用这个辅助函数:

 Stream.of(objects).flatMap(F.instancesOf(Client.class)) .map(Client::getId) .forEach(System.out::println); 

晚会到了,但我认为这是一个有用的答案。

flatMap将是最短的做法。

 Stream.of(objects).flatMap(o->(o instanceof Client)?Stream.of((Client)o):Stream.empty()) 

如果oClient ,则使用单个元素创build一个Stream,否则使用空的stream。 这些stream将被平铺成Stream<Client>

这看起来有点难看。 是否有可能将整个stream转换为不同的types? 像将Stream<Object> Stream<Client>转换为Stream<Client>

不,这是不可能的。 这在Java 8中并不是新鲜事。这是针对generics的。 List<Object>不是List<String>的超types,所以不能只将List<Object>转换为List<String>

类似的问题在这里。 您不能将Stream<Object>Stream<Client> 。 当然你可以这样间接地施放它:

 Stream<Client> intStream = (Stream<Client>) (Stream<?>)stream; 

但这并不安全,在运行时可能会失败。 其根本原因是,Java中的generics是使用擦除来实现的。 因此,在运行时没有关于哪种types的Streamtypes信息。 一切都只是Stream

顺便说一下,你的方法有什么问题? 对我看起来很好。