是否可以在 Java 8 中转换 Stream?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22511750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to cast a Stream in Java 8?
提问by Phiction
Is it possible to cast a stream in Java 8? Say I have a list of objects, I can do something like this to filter out all the additional objects:
是否可以在 Java 8 中转换流?假设我有一个对象列表,我可以执行以下操作来过滤掉所有其他对象:
Stream.of(objects).filter(c -> c instanceof Client)
After this though, if I want to do something with the clients I would need to cast each of them:
不过,在此之后,如果我想对客户做某事,我需要对每个客户进行强制转换:
Stream.of(objects).filter(c -> c instanceof Client)
.map(c -> ((Client) c).getID()).forEach(System.out::println);
This looks a little ugly. Is it possible to cast an entire stream to a different type? Like cast Stream<Object>
to a Stream<Client>
?
这看起来有点难看。是否可以将整个流转换为不同的类型?喜欢强制Stream<Object>
转换为Stream<Client>
?
Please ignore the fact that doing things like this would probably mean bad design. We do stuff like this in my computer science class, so I was looking into the new features of java 8 and was curious if this was possible.
请忽略这样一个事实,做这样的事情可能意味着糟糕的设计。我们在我的计算机科学课上做这样的事情,所以我正在研究 java 8 的新特性,并很好奇这是否可能。
采纳答案by assylias
I don't think there is a way to do that out-of-the-box. A possibly cleaner solution would be:
我不认为有一种开箱即用的方法。一个可能更清洁的解决方案是:
Stream.of(objects)
.filter(c -> c instanceof Client)
.map(c -> (Client) c)
.map(Client::getID)
.forEach(System.out::println);
or, as suggested in the comments, you could use the cast
method - the former may be easier to read though:
或者,正如评论中所建议的那样,您可以使用该cast
方法-尽管前者可能更易于阅读:
Stream.of(objects)
.filter(Client.class::isInstance)
.map(Client.class::cast)
.map(Client::getID)
.forEach(System.out::println);
回答by Rohit Jain
This looks a little ugly. Is it possible to cast an entire stream to a different type? Like cast
Stream<Object>
to aStream<Client>
?
这看起来有点难看。是否可以将整个流转换为不同的类型?喜欢强制
Stream<Object>
转换为Stream<Client>
?
No that wouldn't be possible. This is not new in Java 8. This is specific to generics. A List<Object>
is not a super type of List<String>
, so you can't just cast a List<Object>
to a List<String>
.
不,那是不可能的。这在 Java 8 中并不新鲜。这是泛型特有的。AList<Object>
不是 的超类型List<String>
,因此您不能将 a 强制转换List<Object>
为 a List<String>
。
Similar is the issue here. You can't cast Stream<Object>
to Stream<Client>
. Of course you can cast it indirectly like this:
类似的问题在这里。你不能投射Stream<Object>
到Stream<Client>
. 当然,您可以像这样间接投射它:
Stream<Client> intStream = (Stream<Client>) (Stream<?>)stream;
but that is not safe, and might fail at runtime. The underlying reason for this is, generics in Java are implemented using erasure. So, there is no type information available about which type of Stream
it is at runtime. Everything is just Stream
.
但这并不安全,并且可能在运行时失败。其根本原因是,Java 中的泛型是使用擦除实现的。因此,Stream
在运行时没有关于它是哪种类型的类型信息。一切都只是Stream
。
BTW, what's wrong with your approach? Looks fine to me.
顺便说一句,你的方法有什么问题?对我来说看起来不错。
回答by ggovan
Late to the party, but I think it is a useful answer.
聚会迟到了,但我认为这是一个有用的答案。
flatMap
would be the shortest way to do it.
flatMap
将是做到这一点的最短方法。
Stream.of(objects).flatMap(o->(o instanceof Client)?Stream.of((Client)o):Stream.empty())
If o
is a Client
then create a Stream with a single element, otherwise use the empty stream. These streams will then be flattened into a Stream<Client>
.
如果o
是Client
,则使用单个元素创建一个流,否则使用空流。然后这些流将被展平成一个Stream<Client>
.
回答by Brandon
Along the lines of ggovan's answer, I do this as follows:
沿着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();
}
}
Using this helper function:
使用这个辅助函数:
Stream.of(objects).flatMap(F.instancesOf(Client.class))
.map(Client::getId)
.forEach(System.out::println);