假设我有一个列表,对其执行多个流操作。
bobs = myList.stream()
.filter(person -> person.getName().equals("Bob"))
.collect(Collectors.toList())
...和
tonies = myList.stream()
.filter(person -> person.getName().equals("tony"))
.collect(Collectors.toList())我不能就这么做:
Stream<Person> stream = myList.stream();这意味着我可以:
bobs = stream.filter(person -> person.getName().equals("Bob"))
.collect(Collectors.toList())
tonies = stream.filter(person -> person.getName().equals("tony"))
.collect(Collectors.toList())发布于 2018-07-27 15:36:29
不,你不能。一个Stream只能使用一次,当你尝试重用时,它会抛出错误:
java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)根据Java文档
流应该只操作一次(调用中间流或终端流操作)。
但是,您的查询的一个简洁的解决方案是使用Suplier。如下所示:
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调用都将返回一个新的流。
发布于 2018-07-27 15:48:59
在这种情况下,您可以做的是生成动态流管道。假设管道中唯一的变量是筛选者的姓名。
我们可以将其表示为Function<String, Stream<Person>>,如下所示:
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());发布于 2018-07-27 17:15:08
不,你不能,医生说:
流应该只操作一次(调用中间流或终端流操作)。
但是,您可以使用单个流,只需过滤一次所需的所有元素,然后按所需方式对它们进行分组:
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");https://stackoverflow.com/questions/51561225
复制相似问题