Java 向现有流添加新值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28785833/
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
Adding new value to existing Stream
提问by Dmytro
Is there is a good way to add a new value to existing Stream
? All I can imagine is something like this:
有没有一种好方法可以为现有的添加一个新的值Stream
?我所能想象的是这样的:
public <T> Stream<T> addToStream(Stream<T> stream, T elem ) {
List<T> result = stream.collect(Collectors.toList());
result.add(elem);
return result.stream();
}
But I'm looking for something more concise that I can use in lambda expression without verbosity.
但我正在寻找更简洁的东西,我可以在没有冗长的 lambda 表达式中使用它。
Another question appeared when I tried to implement PECSprinciple:
当我尝试实施PECS原则时,出现了另一个问题:
public <T> Stream<? super T> addToStream(Stream<? super T> stream, T elem ) {
List<? super T> result = stream.collect(Collectors.toList()); //error
result.add(elem);
return result.stream();
}
Seems like wildcard doesn't work with Stream.collect
and I'm wondering why. Thanks in advance.
似乎通配符不起作用Stream.collect
,我想知道为什么。提前致谢。
采纳答案by Brian Goetz
The question belies an incorrect assumption: that streams actually contain their data. They do not; streams are not data structures, they are a means for specifying bulk operations across a variety of data sources.
这个问题掩盖了一个错误的假设:流实际上包含它们的数据。他们不; 流不是数据结构,它们是一种用于指定跨各种数据源的批量操作的方法。
There are combinators for combining two streams into one, such as Stream.concat
, and factories for creating streams from a set of known elements (Stream.of
) or from collections (Collection.stream
). So you can combine these if you want to produce a new stream that is the concatenation of the stream you have in hand, along with a new stream describing the new elements.
有用于将两个流合并为一个的组合子,例如Stream.concat
, 以及从一组已知元素 ( Stream.of
) 或集合 ( Collection.stream
)创建流的工厂。因此,如果您想生成一个新流,该流是您手头的流以及描述新元素的新流的串联,则可以将这些组合起来。
The problem in your PECS example is that you've got three occurrences of ? super T
, and you are assuming they describe the same type, but they do not. Each occurrence of a wildcard corresponds to a unique capture, which isn't what you want; you need to give that type variable a name so the compiler knows that the type of the list and the type of the input stream are the same. (Also, don't materialize a collection; that's expensive, and potentially non-terminating if the stream is not finite. Just use concat.) So the answer is: you just got the generics wrong. Here's one way to do it:
您的 PECS 示例中的问题是您出现了 3 次? super T
,并且您假设它们描述了相同的类型,但事实并非如此。每次出现通配符都对应一个唯一的捕获,这不是您想要的;您需要为该类型变量命名,以便编译器知道列表的类型和输入流的类型是相同的。(另外,不要物化一个集合;这很昂贵,如果流不是有限的,则可能是非终止的。只需使用 concat。)所以答案是:你只是弄错了泛型。这是一种方法:
public<T> Stream<T> appendToStream(Stream<? extends T> stream, T element) {
return Stream.concat(stream, Stream.of(element));
}
You confused yourself with PECS because you were thinking about "inserting" into the stream, when in fact you're consuming from it.
您将自己与 PECS 混淆,因为您正在考虑“插入”到流中,而实际上您正在从中消费。
回答by Eran
How about
怎么样
return Stream.concat(stream, Stream.of(elem));
this is assuming the original Stream is finite. If it's not, you can concat them in a reversed order.
这是假设原始流是有限的。如果不是,您可以以相反的顺序连接它们。
回答by artspb
回答by Solubris
The best way is using a flatMap as follows:
最好的方法是使用 flatMap 如下:
public <T> Stream<T> appendToStream(Stream<T> stream, T element) {
return stream.flatMap(e -> Stream.of(e, element));
}
This operates on the original stream so it can be just another intermediate operation on the stream, eg:
这对原始流进行操作,因此它可以只是流上的另一个中间操作,例如:
stream.flatMap(e -> Stream.of(e, element))
.map(...)
.filter(...)
.collect(Collectors.toList());