Java 8 - Streams Nested ForEach with a different collection

I am trying to understand the new Java 8 threads, and I have been trying for several days to wrap nested foreach loops on top of the collection in Java 8 threads.

Is it possible to reorganize the following nested foreach loops, including if-conditions in Java-8 threads?

If so, what does it look like.

ArrayList<ClassInq> Inq = new ArrayList<>(); TreeMap<String, SalesQuot> Quotations = new TreeMap<>(); ArrayList<ClassInq> tempInqAndQuot = new ArrayList<>(); ArrayList<SalesQuot> tempQuotPos = new ArrayList<>(); for (ClassInq simInq : this.Inq){ if (!simInq.isClosed() && !simInq.isDenied()){ for (Map.Entry<String, SalesQuot> Quot: Quotations.entrySet()){ SalesQuot sapQuot = Quot.getValue(); if (sapQuot.getInquiryDocumentNumber().compareTo(simInq.getSapInquiryNumber()) == 0){ simInq.setSAPQuotationNumber(sapQuot.getQuotationDocumentNumber()); tempInqAndQuot.add(simInq); for (Map.Entry<String, SalesQuotPosition> quotp : sapQuot.getPosition().entrySet()){ tempQuotPos.add(quotp.getValue()); } } } } } 

Many thanks for your help.

BR

+2
source share
1 answer

First, try sticking to Java naming conventions as your uppercase variable names make it very difficult to read your code. Secondly, it’s good that you want to know about the Stream API, but you should not ignore the basics of the pre-Java 8 Collection APIs.

It is not useful to use iteration over entrySet() when you are only interested in keys, or values. You do this twice in a small piece of code.

At the first appearance you can replace

 for (Map.Entry<String, SalesQuot> Quot: Quotations.entrySet()){ SalesQuot sapQuot = Quot.getValue(); 

with simpler

 for (SalesQuot sapQuot: Quotations.values()){ 

Secondly, the whole

 for(Map.Entry<String,SalesQuotPosition> quotp: sapQuot.getPosition().entrySet()){ tempQuotPos.add(quotp.getValue()); } 

can be replaced by

 tempQuotPos.addAll(sapQuot.getPosition().values()); 

Thus, even without threads, your code can be simplified to

 for (ClassInq simInq : this.Inq){ if (!simInq.isClosed() && !simInq.isDenied()){ for (SalesQuot sapQuot: Quotations.values()){ if (sapQuot.getInquiryDocumentNumber().compareTo(simInq.getSapInquiryNumber()) == 0){ simInq.setSAPQuotationNumber(sapQuot.getQuotationDocumentNumber()); tempInqAndQuot.add(simInq); tempQuotPos.addAll(sapQuot.getPosition().values()); } } } } 

although it is still unclear what he should do and whether he is right. Besides the errors and suspicions mentioned in the comments to your question, changing input values ​​(for example, from an external loop) looks wrong.

It is also unclear why you are using ….compareTo(…)==0 , not equals .

However, it can be directly rewritten to use streams without changing any code logic:

 this.Inq.stream().filter(simInq -> !simInq.isClosed() && !simInq.isDenied()) .forEach(simInq -> Quotations.values().stream().filter(sapQuot -> sapQuot.getInquiryDocumentNumber().compareTo(simInq.getSapInquiryNumber())==0) .forEach(sapQuot -> { simInq.setSAPQuotationNumber(sapQuot.getQuotationDocumentNumber()); tempInqAndQuot.add(simInq); tempQuotPos.addAll(sapQuot.getPosition().values()); }) ); 

However, I recommend that you clear the original logic first before rewriting it to use other APIs. The shape of the flow will greatly benefit from a more precise definition of what to achieve.

+11
source

Source: https://habr.com/ru/post/1216006/


All Articles