Java 8 - Streams嵌套ForEach与不同的Collection

use*_*346 2 java collections foreach java-8 java-stream

我尝试了解新的Java 8 Streams,并且我尝试了几天将嵌套的foreach循环转移到Java 8 Streams中的集合上.

是否有可能重构以下嵌套的foreach循环,包括Java-8-Streams中的if-conditions?

如果是的话会是什么样子.

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());
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

非常感谢你的帮助.

BR

Hol*_*ger 13

首先,尝试遵循Java命名约定,因为大写的变量名称使得读取代码变得非常困难.其次,您希望了解StreamAPI 是一件好事,但您不应忽视Java 8之前的CollectionAPI 的基础知识.

entrySet()当你只对键,键或值感兴趣时迭代它是没有用的.你可以在一小段代码中完成两次.

在第一次出现时你可以替换

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

更简单

for (SalesQuot sapQuot: Quotations.values()){
Run Code Online (Sandbox Code Playgroud)

在第二,整个

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

可以替换为

tempQuotPos.addAll(sapQuot.getPosition().values());
Run Code Online (Sandbox Code Playgroud)

因此,即使没有流,您的代码也可以简化为

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());
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

虽然它仍然不清楚它应该做什么以及它是否正确.除了在你的问题的评论中指出的错误和怀疑,修改传入的值(特别是从外部循环)看起来不正确.

它也不清楚为什么你使用….compareTo(…)==0而不是equals.

但是,可以直接重写它以使用流而不更改任何代码的逻辑:

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());
    })
  );
Run Code Online (Sandbox Code Playgroud)

不过,我建议首先清理原始逻辑,然后再重写它以使用其他API.流形式将从更精确的定义中获益.