【问题标题】:Using streams to perform logic [duplicate]使用流执行逻辑
【发布时间】:2016-08-05 01:21:58
【问题描述】:

如何在最后运行一些逻辑而不是收集。

for(SomeObject someObj : someObjectList){
        if (/*some test*/) {
            if (/*more tests*/) {
                // do logic like create new object with the filtered values and add to a list. 
            }
        }
    }

我可以这样做

someObjectList.streams().filter(test).filter(more tests).???

过滤后如何运行最后的逻辑。

谢谢, 拉维

【问题讨论】:

  • 好吧。你想做什么? “做逻辑”不是很具有描述性。
  • .filter(test).filter(more tests).forEach(someObj -> {})
  • 为什么不直接使用完全正常的循环?

标签: java collections java-8 java-stream


【解决方案1】:

调用 .filter(...) 然后调用 .map(...) 来转换 someObjectList 的元素,从而将您的测试与其他对象一致,然后调用 .collect(...)。或者,如果您根本不想使用收集器,请将转换后的对象添加到 .filter(...).map(...).forEach( ... ) 中的预创建列表中。

【讨论】:

    【解决方案2】:

    一种选择是使用forEach,但是如果您要创建对象列表,则应使用collect

    List<Result> results = list.stream()
                               .filter(/*some test*/)
                               .filter(/*more tests*/)
                               .map(x -> new Result(x)) // do logic like create new object
                               .collect(Collectors.toList()) // add to a list. 
    

    函数式编程涉及返回结果并且理想情况下没有任何副作用的函数。但是,每当您看到RunnableConsumer 时,您就会知道这只是为了产生副作用。恕我直言,如果没有简单的替代方案,这很好。但是,在这种情况下,您真的希望创建/返回一个列表,而不是使用 forEach,而 collect(toList()) 是一个更自然/更实用的解决方案。

    【讨论】:

    • 不是一个反对者,但我想这就是为什么当有这么多 终端 操作时你在 collect 上磨练:forEach, @987654330 @,toArray,reduce,collect,min,max,count,anyMatch,allMatch,@9876543@39@,findAny,@9876哎呀,您甚至可以在非终止 peek 中执行“逻辑”,尽管您不应该这样做。
    • @Andreas:OP 在“执行逻辑”代码注释中明确提到“添加到列表”,因此指向 collect(Collectors.toList()) 是合理的。我希望,否决票不是因为缺少分号……
    • @Andreas OP 专门要求将新对象添加到列表中,而 Stream 方法是使用 mapcollect(toList())
    • @Andreas 添加了一条说明,说明如果您想要函数式编程,为什么应该避免使用 forEach。 +1
    猜你喜欢
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    相关资源
    最近更新 更多