简体   繁体   English

在Java 8中迭代2个对象和1个嵌套对象

[英]Iterate through 2 objects and 1 nested object in Java 8

I have the following structure: 我有以下结构:

class Object1 {
   String id;
   Integer total;
}
class Object2 {
   String id;
   List<Object3> list;
}
class Object3 {
   Integer total;
}

When Object1 and Object2 have the same id I need to update the total from Object1 by summing up the total from all the Object3 within the list inside Object2 and subtracting from Object1 total . Object1Object2具有相同的id我需要更新的total通过总结从Object1 total从所有Object3的内listObject2和减去Object1 total

It works like this without java 8 : 它没有java 8就像这样工作:

for (Object1 object1 : list1) {
     for (Object2 object2 : list2) {
          if (object1.getId().equals(object2.getId())) {
              int total = 0;
              for (Object3 object3 : object2.getlist3()) {
                   total += object3.getTotal();
              }
              object1.setTotal(object1.getTotal() - total);
          }
     }
}

This is what I have so far using Java 8 : 这是我到目前为止使用Java 8

list1.forEach(object1 -> list2.stream()
     .filter(object2 ->object2.getId().equals(object1.getId()))

But I don't know how to proceed with the logic because I am not very familiar with Java 8. Could someone help me out? 但我不知道如何继续使用逻辑,因为我对Java 8不是很熟悉。有人可以帮助我吗?

Try this. 尝试这个。 Explanations are inline as comments 解释内容为注释

list1.forEach(object1 -> 
    object1.setTotal(
        object1.getTotal() - list2.stream()
            .filter(object2 -> object1.getId().equals(object2.getId()))
            .flatMap(object2 -> object2.getList3().stream()) // Stream<Object2> to Stream<Object3>
            .mapToInt(Object3::getTotal)                     // get each total
            .sum()                                           // sum them
    )
);

It is worth noting that you are calling object1.setTotal multiple times if more than one ID matches, effectively overriding the previous result. 值得注意的是,如果多个ID匹配,则多次调用object1.setTotal ,从而有效地覆盖先前的结果。 You may say that this is fine, and that the lists are populated in a such a way that there will only be one matching ID. 您可以说这很好,并且列表的填充方式只有一个匹配的ID。 In which case, you should add a break statement after object1.setTotal . 在这种情况下,您应该在object1.setTotal之后添加break语句。 This will avoid iterating over the remaining elements in list2 unnecessarily. 这将避免不必要地迭代list2的其余元素。 A similar performance enhancement in a stream would require a significant change to the above example. 流中的类似性能增强将需要对上述示例进行重大改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM