3

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

Grzegorz Piwowarek
  • 13,172
  • 8
  • 62
  • 93

1 Answers1

5

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

            .
Grzegorz Piwowarek
  • 13,172
  • 8
  • 62
  • 93
  • That doesn't work. I think it's because calculateSalesKpis() does not return a single OutputDataType object but a list of OutputDatatype objects... – Bofrostmann Nov 16 '16 at 17:22
  • collect (java.util.stream.Collector super java.util.List,A,R>) in Stream cannot be applied to (java.util.stream.Collector,java.util.List>) – Bofrostmann Nov 16 '16 at 17:23
  • 1
    @Bofrostmann I did more changes but without the rest of your code it's just guessing. Try now – Grzegorz Piwowarek Nov 16 '16 at 17:24
  • I think this could work now? `resultList = 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());` – Bofrostmann Nov 16 '16 at 17:25
  • Same idea :D yes thank you! Sorry for that bad formatting..still new to Stack Overflow.. – Bofrostmann Nov 16 '16 at 17:26