【问题标题】:Java streams replace nested for loopJava 流替换了嵌套的 for 循环
【发布时间】:2016-04-13 21:51:43
【问题描述】:

我有一个嵌套的 for 循环,我想用流替换,但如果可能的话,我不知道该怎么做。基本循环如下

for (Object outer : owner.getOuterList())
    for (Object inner : owner.getInnerList())
        if (cond(outer, inner))
            func(outer, inner);
        else
            moo(outer, inner);

我能够到达的唯一解决方案基本上看起来完全一样,使用forEach 而不是循环。 flatMap 似乎适用,但我不知道如何获取这两个列表。

【问题讨论】:

  • 如果这些纯粹是必要的事情,那么是的,它看起来完全一样。流通常用于转换和过滤以及取出 元素。
  • 是的,@Pillar 链接基本上就是您所需要的。 .flatMap(outer -> owner.getInnerList().stream().map(inner -> new Object[] { outer, inner })) 问题总是有一个 Tuple 类来保存 innerouter。因为它们都是Object,所以我们可以滥用数组...总而言之:保持for 循环。
  • 好的,谢谢 Pillar 和 Tunaki。有点糟糕,没有一种更简洁的方式来编写它。

标签: java java-stream


【解决方案1】:

主要问题是内部循环体

if (cond(outer, inner))
    func(outer, inner);
else
    moo(outer, inner);

在 Stream API 中没有对应物,并且对于大多数可想到的解决方案来说仍然是一个不透明的操作,因此最简单的解决方案是将其表示为 Consumer,您可以使用嵌套的 forEach 调用它,这对嵌套 for 循环你已经有了。

如果您想强制执行基于 flatMap 的解决方案,您可以执行以下操作:

owner.getOuterList().stream().flatMap(
    outer -> owner.getInnerList().stream().<Runnable>map(
        inner -> cond(outer, inner)? () -> func(outer, inner): () -> moo(outer, inner))
).forEach(Runnable::run);

它不需要 Pair/Tuple 类型来映射到 [outer,inner],因为函数本身能够捕获这些值。请注意,这将评估内部流处理中的条件,但funcmoo 的实际调用将发生在外部流处理中。您可以使用

强制处理外部流中的所有内容
owner.getOuterList().stream().flatMap(
    outer -> owner.getInnerList().stream().<Runnable>map(
        inner -> () -> { if(cond(outer,inner)) func(outer,inner); else moo(outer,inner); })
).forEach(Runnable::run);

如前所述,它将原始内部循环的主体视为不透明的动作。

我认为,很明显,这两者都不是真正战胜原来的嵌套 for 循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-06
    • 2016-07-14
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 2010-10-03
    • 2018-05-21
    相关资源
    最近更新 更多