有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java有没有办法将这些嵌套的IntStreams扁平化为一个?有更短的路吗?

我将4个嵌套的for循环更改为嵌套的IntStream,但这个解决方案看起来不太好。我不知道怎么把它缩短?我应该以某种方式使用flatmap

IntStream.range(0, totalCluster).forEach(numCluster ->{
  writeToFile("Cluster__________________________" + numCluster);
  IntStream.range(0, totalAgency).forEach(numAgency ->{
    writeToFile("\n\tCluster_" + numCluster + "_Agency_" + numAgency);
    IntStream.range(0, totalProgramArea).forEach(numProgramArea ->IntStream.range(0, totalUsers).forEach(numUser ->{
      writeToFile("\n\t\t\tAgency_" + numAgency + "_" + "ProgramArea_" + numProgramArea + "_User_" + numUser);
    }));
  });
});

共 (1) 个答案

  1. # 1 楼答案

    您可能在询问表单中的构造

    IntStream.range(0, 2)
      .flatMap(i -> IntStream.range(0, 2))
      .flatMap(i -> IntStream.range(0, 2))
      .forEach(i -> /*... inner loop logic here ..*/ );
    

    然而,如果您需要最内部逻辑中每个外部循环的每次迭代的索引,那么没有很好的方法。你的问题的答案是-老式for循环在这里工作得更好

    不过,这里有一个例子(我减少了混乱以提高可读性):

    IntStream.range(0, totalClusters).boxed()
      .flatMap(i -> IntStream.range(0, totalAgencies).mapToObj(j -> new int[]{i,j})). 
      .flatMap(k -> IntStream.range(0, totalAreas).mapToObj(j -> new int[]{k[0],k[1],j}))
      .forEach(o -> System.out.println(Arrays.toString(o)));
    

    它会打印

    [0, 0, 0]
    [0, 0, 1]
    ...
    [1, 1, 1]
    

    这段代码的问题是,必须在堆上分配int数组,而不是使用堆栈中的循环计数器。为了简单起见,我只使用了int[],这不是一个好的实践,实际上最好使用一些上下文对象

    你可以从这里得出一个解决方案的想法

    现在,人们经常会问,是否有一种处理嵌套for循环的正确功能方法。在Haskell这样的语言中,您会使用这样的语言,因为列表是单子(或列表理解):

    do
      i <- [0..2]
      j <- [0..3]
      return $ i*100 + j
    

    通过创建自己的函数组合器库,您完全可以在Java中使用类似的do符号逻辑。尽管这是可能的,但与Scala不同的是,Java的语法阻止了最终结果看起来比老式的for循环更好,在这种特殊情况下