当前位置: 首页 > 知识库问答 >
问题:

Java8-具有不同集合的嵌套ForEach流

郭建华
2023-03-14

我试图理解新的Java8流,并且花了好几天的时间在Java8流中的集合上传输嵌套的foreach循环。

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

如果是,它会是什么样子。

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

非常感谢你的帮助。

共有1个答案

祁宝
2023-03-14

首先,尝试遵守Java命名约定,因为大写的变量名使代码很难读取。其次,您希望了解StreamAPI是件好事,但不应忽略前Java的基础知识

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

第一次出现时,您可以替换

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

用更简单的

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

在第二,整个

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

可以用

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

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

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

虽然现在还不清楚它应该做什么,是否正确。除了问题注释中提到的错误和怀疑之外,修改传入值(特别是来自外部循环)看起来并不正确。

也不清楚为什么要使用...... 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());
    })
  );

尽管如此,我还是建议先清理原始逻辑,然后再为使用其他API重写它。流形式将从更精确的定义中受益匪浅。

 类似资料:
  • 我有一个对象的集合,每个对象都有一个元素的集合,例如: 如何使用Java 8函数式编程来过滤和收集类型等于“a”的集合? 我尝试了以下方法: 但我得到以下错误: 变量'filteredChildren'初始值设定项'parents。stream()。forEach(p- 如何按类型筛选嵌套集合并收集它们?

  • 我想要一个函数,该函数可以执行以下操作: 更一般地说,是否存在与此模式匹配的typeclass?

  • 问题内容: 我在Scala和Java之间遇到编译问题。 我的Java代码需要一个 我的scala代码有一个 我收到编译错误: 似乎scala.collection.JavaConversions不适用于嵌套集合,即使Vector可以隐式转换为Iterable。除了遍历scala集合并手动进行转换之外,我还能做些什么使这些类型起作用? 问题答案: 应该弃用恕我直言。您最好使用来明确说明转换的时间和地

  • 我有一个这样的数组 我想做的是前面的模型,为其数量绘制徽标,因此三星=3,索尼=7,以此类推,将绘制3个索尼徽标和7个三星徽标。 我想出了这样的办法 但是当然,所有这些都是为了每个数组条目,呼应出名称,所以我最终打印了5个三星,打印了5个索尼,等等。 如何使其使用 qty 数组的值而不是条目数?

  • 问题内容: 我有一个对象A的列表。此列表中的每个对象A都包含对象B的列表,而对象B包含对象C的列表。对象C包含一个属性名称,我想使用它使用Java 8进行过滤。 如何使用流在Java 8中编写以下代码以避免嵌套循环: 问题答案: 您可以使用两个,然后使用a,然后可以选择第一个,或者如果没有结果返回:

  • 我有一个对象列表A。此列表中的每个对象A都包含对象B的列表,对象B包含对象C的列表。对象C包含一个属性名称,我想使用java 8进行过滤。 如何使用流在java8中编写下面的代码以避免嵌套循环: