Java流、过滤器,然后对生成的集合执行某些操作

Java流、过滤器,然后对生成的集合执行某些操作,java,java-stream,Java,Java Stream,目标 final List<T> listOfThings = ...; listOfThings.stream() .filter(...) // returns a Stream<T> .then(filteredListOfThings -> { // How do I get here so I can work on the newly filtered collection // in a fluent

目标

final List<T> listOfThings = ...;

listOfThings.stream()
    .filter(...) // returns a Stream<T>
    .then(filteredListOfThings -> {
        // How do I get here so I can work on the newly filtered collection
        // in a fluent way w/out collecting the result to a variable?
        // For example, if I need to process the elements but don't 
        // care about them in their current form outside this chain.
    });
物品的最终清单=。。。;
流()的列表
.filter(…)//返回一个流
.然后(filteredListOfThings->{
//我如何到达这里,以便处理新筛选的集合
//以流畅的方式将结果收集到变量?
//例如,如果我需要处理元素,但不需要
//关心他们在这个链条之外的当前形式。
});
问题

在英语中,给定一个列表,我想对列表进行流式处理、过滤,然后对整个过滤结果进行操作。我可以用可选的方式来完成这项任务,但在IMO中这不是很干净:

final List<T> listOfThings = ...;

Optional
    .of(listOfThings.stream()
        .filter(...) // returns a Stream<T>
        .collect(Collectors.toList()))
    .map(filteredListOfThings -> {
        // I'm here, now, but would like to not have to wrap it in an Optional<T>
    });
物品的最终清单=。。。;
可选的
.of(listOfThings.stream)()
.filter(…)//返回一个流
.collect(收集器.toList())
.map(filteredListOfThings->{
//我现在在这里,但不想用可选的
});

如果在
上有一个
然后
或类似的方法,它返回
,允许进一步链接,这允许我在lambda中处理整个结果集,而不声明外部变量。

不要让它变得比需要的更复杂

将收集的结果分配给变量,然后对该变量进行操作:

List<T> filteredListOfThings = ... .collect(toList());

// Now use filteredListOfThings.
List filteredListOfThings=。收集(toList());
//现在使用filteredListOfThings。
filteredListOfThings
将始终有一个值,即使它是空列表,因此使用
可选的
没有意义

作为lambda参数的
filteredListOfThings
和作为显式变量的
filteredListOfThings在语法上没有太大区别;但在处理过程中,您可以更灵活地执行操作(从方法返回、抛出已检查的异常等)

我想对列表进行流式处理、过滤,然后对整个过滤结果进行操作

请注意,流也可以是无限的;)

因此,获得无限的结果列表不是一个好主意

基本上,流是惰性的,在没有终端操作的情况下对流应用中间操作不会产生任何效果:

Stream<String> stream = Stream.of("hello","how","are", "you").filter(this::startsWithH)

private boolean startsWithH(String elem) {
  System.out.println("Filtering element " + elem); 
  return elem.startsWith("h");
}
例如,以下代码不打印任何内容:

Stream<String> stream = Stream.of("hello","how","are", "you").filter(this::startsWithH)

private boolean startsWithH(String elem) {
  System.out.println("Filtering element " + elem); 
  return elem.startsWith("h");
}
Stream-Stream=Stream.of(“你好”、“怎么样”、“你”).filter(this::startsWithH)
私有布尔startsWithH(字符串元素){
System.out.println(“过滤元件”+elem);
返回元素STARTSTWITH(“h”);
}
现在,当您应用终端操作时,它仍然会逐个元素工作,通常:

执行示例:

Stream<String> stream = Stream.of("hello","how","are", "you")
.filter(this::startsWithH)
.map(String::toUpperCase)

stream.collect(toList());
Stream-Stream=Stream.of(“你好”、“你好”、“你好”、“你”)
.filter(this::startsWithH)
.map(字符串::toUpperCase)
stream.collect(toList());
此示例生成以下执行链:

  • 过滤器(“你好”)
  • 地图(“你好”)
  • 过滤器(“如何”)
  • 地图(“如何”)

  • 过滤(“are”)你对过滤的集合的目标是什么?预期的输出是什么?你可以对过滤的流执行
    map
    操作
    listOfThings.stream().filter(-).map(-)
    将其分配给一个变量,对该变量执行一些操作。你正在寻找
    flatmap
    ?完全有效,另一个方面:当你想“对整个列表做点什么”时,意味着不是每个元素都单独处理,而是需要知道其他元素(如最小值、最大值或不同值)您可以使用Stream.reduce方法。当然可以,但问题是是否有这样一个API可以流畅地启用此功能?看起来确实没有。在我看来,使用lambda和外部变量之间有区别,就代码而言,在这种情况下不必创建外部变量。(通过“外部变量”我的意思是在链接的
    调用之外。)是的,谢谢。我完全理解流不一定是有限的,但通过询问
    然后
    选项来收集结果与你收集流(有/没有限制)时没有什么不同。它只是一个流畅的助手。