首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向现有流添加新价值

向现有流添加新价值
EN

Stack Overflow用户
提问于 2015-03-01 03:21:36
回答 4查看 44.8K关注 0票数 86

有没有向现有Stream添加新值的好方法?我所能想象的就是这样:

代码语言:javascript
复制
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原则时,出现了另一个问题:

代码语言:javascript
复制
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,我想知道为什么。提前谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-03-01 04:11:15

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

存在用于将两个流组合成一个流的组合器(例如Stream.concat ),以及用于从一组已知元素(Stream.of)或从集合(Collection.stream)创建流的工厂。因此,如果您想要生成一个新的流,它是现有流的串联,以及描述新元素的新流,则可以将这些流组合在一起。

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

代码语言:javascript
复制
public<T> Stream<T> appendToStream(Stream<? extends T> stream, T element) {
    return Stream.concat(stream, Stream.of(element));
}

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

票数 100
EN

Stack Overflow用户

发布于 2015-03-01 03:26:42

怎么样

代码语言:javascript
复制
return Stream.concat(stream, Stream.of(elem));

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

票数 41
EN

Stack Overflow用户

发布于 2018-06-01 19:00:55

StreamEx库有相应的#prepend()#append()方法。下面是一个如何使用它们的示例:

代码语言:javascript
复制
StreamEx.of("second").prepend("first").append("third").forEach(System.out::println);

输出如下:

代码语言:javascript
复制
first
second
third
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28785833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档