Java 向现有流添加新值

Java 向现有流添加新值,java,java-8,wildcard,Java,Java 8,Wildcard,是否有一种好方法可以向现有的流添加新值?我所能想象的是这样的: public <T> Stream<T> addToStream(Stream<T> stream, T elem ) { List<T> result = stream.collect(Collectors.toList()); result.add(elem); return result.stream(); } publicstream addToStr

是否有一种好方法可以向现有的
流添加新值
?我所能想象的是这样的:

public <T> Stream<T> addToStream(Stream<T> stream, T elem ) {
    List<T> result = stream.collect(Collectors.toList());
    result.add(elem);
    return result.stream();
}
publicstream addToStream(Stream-Stream,T元素){
列表结果=stream.collect(Collectors.toList());
结果:添加(元素);
返回result.stream();
}
但我在寻找更简洁的东西,我可以在lambda表达式中使用,而不需要冗长

当我试图实施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();
}
公共流怎么样

return Stream.concat(stream, Stream.of(elem));

这是假设原始流是有限的。如果不是,您可以按相反的顺序对它们进行分析。

这个问题掩盖了一个错误的假设:流实际上包含它们的数据。他们没有;流不是数据结构,它们是跨各种数据源指定批量操作的一种方法

有用于将两个流合并为一个流的组合器,例如
Stream.concat
,还有用于从一组已知元素(
Stream.of
)或集合(
Collection.Stream
)创建流的工厂。因此,如果您想要生成一个新的流,它是您手头的流的串联,以及一个描述新元素的新流,那么您可以将它们结合起来

PECS示例中的问题是出现了三次
?super T
,您假设它们描述的是相同的类型,但它们不是。每次出现通配符都对应一个唯一的捕获,这不是您想要的;您需要为该类型变量指定一个名称,以便编译器知道列表的类型和输入流的类型是相同的。(另外,不要具体化一个集合;这很昂贵,如果流不是有限的,则可能是不终止的。只需使用concat即可。)因此答案是:您只是把泛型搞错了。这里有一种方法:

public<T> Stream<T> appendToStream(Stream<? extends T> stream, T element) {
    return Stream.concat(stream, Stream.of(element));
}
publicstream appendToStream(Stream库中有相应的
#prepend()
#append()
方法。下面是如何使用它们的示例:

StreamEx.of("second").prepend("first").append("third").forEach(System.out::println);
输出如下:

first
second
third
public <T> Stream<T> appendToStream(Stream<T> stream, T element) {
    return stream.flatMap(e -> Stream.of(e, element));
}

最好的方法是使用平面图,如下所示:

first
second
third
public <T> Stream<T> appendToStream(Stream<T> stream, T element) {
    return stream.flatMap(e -> Stream.of(e, element));
}

无法保证从
collect(Collectors.toList())
返回的
列表
支持
添加
,您可以使用
收集器。toCollection
来选择您获得的列表类型。该方法不应命名为“appendToStream”?否则,我认为concat方法的参数应该被切换。
concat
方法可以使用,但不会太多,来自javadoc:在通过重复连接构造流时要小心。访问深度连接流的元素可能会导致深度调用链,甚至StackOverflowException。不错!尽管是另一个libraY.在通过重复连接构造流时要小心。访问深度连接流的元素可能会导致深度调用链,甚至StackOverflowException。您希望添加元素多少次?:D盎司用于流,或在原始流中每个元素一次?