Bofrostmann Bofrostmann - 23 days ago 7
Java Question

3 nested for-each loops as Java Stream (or better parallel stream)

On the project I am currently working on, we have this construct of three nested for loops:

List<OutputDataType> resultList = new ArrayList<>();

for (OrgStructureEntity product : products) {

for (String region : regions) {

for (SalesType salesType : SalesType.values()) {

resultList.addAll(new SalesRequest(getConnection(),
product.getProductMainGroup(), product.getSbu(), planYear, currentPeriod, region, salesType,
exchangeRates).calculateSalesKpis());
}
}
}


products and regions are both Sets.
resultList is an ArrayList with "OutputDataType" objects.
The method calculateSalesKpis() also returns a list of "OutputDataType" objects.
All these objects are supposed to be added to the resultList. I would like to do all this with parallel streams to make it faster, but I didn't get much further than this:

products.stream()
.map(product -> regions.stream()
.map(region -> Arrays.stream(SalesType.values())
.map(salesType -> new SalesRequest(getConnection(),
product.getProductMainGroup(), product.getSbu(), planYear, currentPeriod, region, salesType,
exchangeRates).calculateSalesKpis())))
.


I don't know how to put it all in the result list now and how to close the stream correctly.
I hope you can help me :)

Answer

In order to avoid working on Stream>, you need to flatten your nested Stream structure using the flatmap method before performing a collection:

products.stream()
  .flatMap(product -> regions.stream()
    .flatMap(region -> Arrays.stream(SalesType.values())
     .flatMap(salesType -> new SalesRequest(getConnection(),
       product.getProductMainGroup(), product.getSbu(), planYear, currentPeriod, region, salesType, exchangeRates).calculateSalesKpis().stream())))
  .collect(Collectors.toList())

            .