Java 8 - 使用不同集合嵌套 ForEach 的流

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25357043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:11:34  来源:igfitidea点击:

Java 8 - Streams Nested ForEach with different Collection

javacollectionsforeachjava-8java-stream

提问by user1796346

I try to understand the new Java 8 Streams and I tried for days to transfer nested foreach loops over collection in Java 8 Streams.

我试图了解新的 Java 8 Streams,并且我尝试了几天在 Java 8 Streams 中通过集合传输嵌套的 foreach 循环。

Is it possible to refactor the following nested foreach loops including the if-conditions in Java-8-Streams?

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

If yes what would 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());
                }
            }
        }
    }
}

Thanks a lot for your help.

非常感谢你的帮助。

BR

BR

采纳答案by Holger

First, try to adhere to the Java naming conventions, as your upper case variable names make it really hard to read your code. Second, it's a good thing that you want to learn about StreamAPI but you should not ignore the basics of the pre-Java?8 CollectionAPIs.

首先,尽量遵守 Java 命名约定,因为大写的变量名会让代码很难阅读。其次,您想了解StreamAPI是一件好事,但您不应忽略 Java?8 之前的CollectionAPI的基础知识。

It's not useful to iterate over an entrySet()when you are only interested in either, keys or values. You do it two times within a small piece of code.

entrySet()当您只对键或值感兴趣时,迭代 an 是没有用的。您可以在一小段代码中执行两次。

At the first appearance you can replace

在第一次出现时,您可以更换

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

with the simpler

用更简单的

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

At the second, the entire

第二,整个

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 streams, 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());
                }
            }
        }
    }

though it's still not clear what it is supposed to do and whether it's correct. Besides the errors and suspicions named in the comments to your question, modifying the incoming values (esp. from the outer loop) does not look right.

虽然目前还不清楚它应该做什么以及它是否正确。除了对您的问题的评论中提到的错误和怀疑之外,修改传入值(特别是来自外部循环)看起来也不正确。

It's also not clear why you are using ….compareTo(…)==0rather than equals.

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

However, it can be straight-forwardly rewritten to use streams without changing any of the code's 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());
    })
  );

Still, I recommend cleaning up the original logic first before rewriting it for using other APIs. The stream form would greatly benefit from a more precise definition of what to achieve.

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