【问题标题】:How can use stream for a recusion in Java 8?如何在 Java 8 中使用流进行递归?
【发布时间】:2021-04-16 03:15:46
【问题描述】:

我有一个这样的方法,我用普通循环递归:

//    example for the args: "START" "RUN" "RUN" "END" "RUN" "START" "RUN" "END" "RUN"
//    expect: Listof.("START" "RUN" "RUN" "END", "START" "RUN" "END")
static List<String[]> findValidCommands(String[] args, List<String[]> listCommands) {

        for (int i = 0; i < args.length; i++) {
            if (args[i].matches("START")) {
                for (int j = i + 1; j < args.length; j++) {
                    if ("END".equals(args[j])) {
                        listCommands.add(Arrays.copyOfRange(args, i, ++j));
                        return findValidCommands(Arrays.copyOfRange(args, j, args.length), listCommands);
                    }
                }
            }
        }
        return listCommands;
    }

我是初学者,请帮助我使用 Stream 改进我的代码。

【问题讨论】:

  • 你到底想做什么?您是否只是想找到成对的 START 和 END?我不明白为什么这应该是递归的。另外,请注意,流不一定“改进”您的代码。如果你认为每个 for 循环都应该在流中重写,那你就太痴迷于流了 :)
  • -“你只是想找到成对的 START 和 END 吗?”,这就是我想要做的。 - “我不明白为什么这应该是递归的”,我不知道任何其他方式,你能告诉我怎么做吗,谢谢。
  • 只需将递归调用替换为break; 会不会给您带来任何不同的结果?
  • 啊,我明白了。 i = j - 1; 然后break; 应该可以完成这项工作。但实际上,这真的不是应该在流中完成的事情。我认为代码比循环更丑陋。我试着只用break; 做这个版本,它已经很可怕了。
  • 哦,当我替换它时它会给出相同的结果。更多,你认为它有另一种方法来代替使用两个 For 循环和两个 If- 条件吗?

标签: java performance optimization java-8 stream


【解决方案1】:

Stream逻辑无法改进代码,恰恰相反。

但是可以通过不使用嵌套循环和不使用递归来改进它。

static List<String[]> findValidCommands(String... args) {
    List<String[]> listCommands = new ArrayList<>();
    for (int start = -1, i = 0; i < args.length; i++) {
        if (start == -1 && args[i].equals("START")) {
            start = i;
        } else if (start != -1 && args[i].equals("END")) {
            listCommands.add(Arrays.copyOfRange(args, start, i + 1));
            start = -1;
        }
    }
    return listCommands;
}

测试

List<String[]> listCommands = findValidCommands(
        "START", "RUN", "RUN", "END", "RUN", "START", "RUN", "END", "RUN");
System.out.println(listCommands.stream().map(Arrays::toString).collect(Collectors.joining(", ")));

输出

[START, RUN, RUN, END], [START, RUN, END]

【讨论】:

  • 哦,非常感谢,你真的救了我一天
猜你喜欢
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 2022-09-26
  • 2014-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多