在Java 8中可以转换流吗?假设我有一个对象列表,我可以这样做来过滤掉所有额外的对象:
Stream.of(objects).filter(c -> c instanceof Client)
在这之后,如果我想对客户端做一些事情,我需要对他们每个人都进行casting:
Stream.of(objects).filter(c -> c instanceof Client)
.map(c -> ((Client) c).getID()).forEach(System.out::println);
这看起来有点难看。是否可以将整个流转换为不同的类型?比如将流<对象>转换为流<客户端>?
请忽略这样做可能意味着糟糕设计的事实。我们在计算机科学课上做过类似的事情,所以我在研究java 8的新功能,并想知道这是否可行。
这看起来有点难看。是否可以将整个流转换为不同的类型?比如将流<对象>转换为流<客户端>?
不,那不可能。这在Java 8中并不新鲜。这是特定于泛型的。List<Object>不是List<String>的超类型,因此不能将List<Object>强制转换为List<String>。
这里的问题也类似。不能将流<对象>转换为流<客户端>。当然,你可以像这样间接地转换它:
Stream<Client> intStream = (Stream<Client>) (Stream<?>)stream;
但这并不安全,可能会在运行时失败。这背后的原因是,Java中的泛型是使用擦除实现的。因此,在运行时没有关于它是哪种类型的流的类型信息。一切都是流。
顺便问一下,你的方法有什么问题?我看还好。
我不认为有什么方法可以开箱即用。一个可能更清洁的解决方案是:
Stream.of(objects)
.filter(c -> c instanceof Client)
.map(c -> (Client) c)
.map(Client::getID)
.forEach(System.out::println);
或者,正如评论中建议的那样,你可以使用强制转换方法——前者可能更容易阅读:
Stream.of(objects)
.filter(Client.class::isInstance)
.map(Client.class::cast)
.map(Client::getID)
.forEach(System.out::println);