为现有流添加新价值

2022-08-31 10:43:54

有没有一个好方法可以为现有值添加新价值?我能想象到的就是这样的事情:Stream

public <T> Stream<T> addToStream(Stream<T> stream, T elem ) {
    List<T> result = stream.collect(Collectors.toList());
    result.add(elem);
    return 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();
}

似乎通配符不起作用,我想知道为什么。提前致谢。Stream.collect


答案 1

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

有用于将两个流合并为一个的组合器,例如 ,以及用于从一组已知元素 () 或集合 () 创建流的工厂。因此,如果要生成一个新流(即手头流的串联)以及描述新元素的新流,则可以将这些组合在一起。Stream.concatStream.ofCollection.stream

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

public<T> Stream<T> appendToStream(Stream<? extends T> stream, T element) {
    return Stream.concat(stream, Stream.of(element));
}

你把自己和PECS混淆了,因为你正在考虑“插入”到流中,而实际上你正在从中消费。


答案 2

怎么样

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

这是假设原始流是有限的。如果不是,则可以按相反的顺序连接它们。


推荐