首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >缓存Java 8流

缓存Java 8流
EN

Stack Overflow用户
提问于 2018-07-27 15:34:09
回答 4查看 1.8K关注 0票数 3

假设我有一个列表,对其执行多个流操作。

代码语言:javascript
复制
  bobs = myList.stream()
        .filter(person -> person.getName().equals("Bob"))
        .collect(Collectors.toList())

...

代码语言:javascript
复制
  tonies = myList.stream()
        .filter(person -> person.getName().equals("tony"))
        .collect(Collectors.toList())

我不能就这么做:

代码语言:javascript
复制
Stream<Person> stream = myList.stream();

这意味着我可以:

代码语言:javascript
复制
  bobs = stream.filter(person -> person.getName().equals("Bob"))
        .collect(Collectors.toList())
  tonies = stream.filter(person -> person.getName().equals("tony"))
        .collect(Collectors.toList())
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-07-27 15:36:29

不,你不能。一个Stream只能使用一次,当你尝试重用时,它会抛出错误:

代码语言:javascript
复制
java.lang.IllegalStateException: stream has already been operated upon or closed
       at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)

根据Java文档

流应该只操作一次(调用中间流或终端流操作)。

但是,您的查询的一个简洁的解决方案是使用Suplier。如下所示:

代码语言:javascript
复制
Supplier<Stream<Person>> streamSupplier = myList::stream;
bobs = streamSupplier.get().filter(person -> person.getName().equals("Bob"))
        .collect(Collectors.toList())
tonies = streamSupplier.get().filter(person -> person.getName().equals("tony"))
        .collect(Collectors.toList())

但是,每个get调用都将返回一个新的流。

票数 4
EN

Stack Overflow用户

发布于 2018-07-27 15:48:59

在这种情况下,您可以做的是生成动态流管道。假设管道中唯一的变量是筛选者的姓名。

我们可以将其表示为Function<String, Stream<Person>>,如下所示:

代码语言:javascript
复制
final Function<String, Stream<Person>> pipelineGenerator = name -> persons.stream().filter(person -> Objects.equals(person.getName(), name));

final List<Person> bobs = pipelineGenerator.apply("bob").collect(Collectors.toList());

final List<Person> tonies = pipelineGenerator.apply("tony").collect(Collectors.toList());
票数 1
EN

Stack Overflow用户

发布于 2018-07-27 17:15:08

不,你不能,医生说:

流应该只操作一次(调用中间流或终端流操作)。

但是,您可以使用单个流,只需过滤一次所需的所有元素,然后按所需方式对它们进行分组:

代码语言:javascript
复制
Set<String> names = ...; // construct a sets containing bob, tony, etc
Map<String,List<Person>> r = myList.stream()
                                   .filter(p -> names.contains(p.getName())
                                   .collect(Collectors.groupingBy(Person::getName);
List<Person> tonies = r.get("tony");
List<Person> bobs = r.get("bob");
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51561225

复制
相关文章

相似问题

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