简体   繁体   English

有没有办法将这些嵌套的 IntStreams 合并为一个? 有更短的方法吗?

[英]Is there any way to flatten these nested IntStreams into one? Is there shorter way?

I changed 4 nested for loops to nested IntStream but this solution doesn't look good.我将 4 个嵌套的for循环更改为嵌套的IntStream但此解决方案看起来不太好。 I don't know how to make it shorter?不知道怎么缩短? Should I use flatmap in some way?我应该以某种方式使用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);
    }));
  });
});

You are probably asking about a construct in form您可能正在询问形式上的构造

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

However, if you need the index of each iteration of every outer loop inside the innermost logic, there is no nice way of doing it.但是,如果您需要最内层逻辑中每个外循环的每次迭代的索引,则没有好的方法可以做到。 The answer to your question is - old fashioned for loops work better here .你的问题的答案是老式的 for 循环在这里工作得更好

Still, here is one example (I reduced clutter to improve readability):不过,这里有一个例子(我减少了混乱以提高可读性):

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)));

It prints它打印

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

The problem with this code is that you have to allocate int arrays on heap instead of using loop counters from stack.此代码的问题在于您必须在堆上分配 int 数组,而不是使用堆栈中的循环计数器。 I only used int[] for simplicity, it is not a good practice, in reality it is better to use some context object.我只是为了简单起见使用了int[] ,这不是一个好习惯,实际上最好使用一些上下文对象。

You can derive an idea of a solution from here.您可以从这里获得解决方案的想法。

Now, people often ask if there is a proper functional way of dealing with nested for loops.现在,人们经常问是否有一种合适的函数方式来处理嵌套的 for 循环。 In a language like Haskell, you would use something like this, because lists are monads (or list comprehensions):在像 Haskell 这样的语言中,你会使用这样的东西,因为列表是单子(或列表推导式):

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

You can definitely go for similar do-notation logic in Java, by creating your own library of function combinators.通过创建自己的函数组合器库,您绝对可以在 Java 中使用类似的 do-notation 逻辑。 Even though it is possible, unlike in Scala, syntax of Java prevents the end result from looking better than old fashioned for loops, in this particular case.尽管有可能,但与 Scala 不同,在这种特殊情况下,Java 的语法阻止了最终结果看起来比老式 for 循环更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM