在Java8中迭代并映射两个列表

在Java8中迭代并映射两个列表,java,Java,我有两份清单: 列表1:Object1(名称1,id1) 列表2:Object2(名称2,id2) 给定list1的大小与list2相同 我想迭代list2,如果list2的name2不为null,则更新list1的name1 以下是使用旧java的代码: for(Object1 obj1:list1) { for(Object2 obj2:list2) { if(obj1.getId1.equals(obj2.getId2)) { obj1.setNam

我有两份清单:

  • 列表1:Object1(名称1,id1)
  • 列表2:Object2(名称2,id2)
  • 给定list1的大小与list2相同

    我想迭代list2,如果list2的name2不为null,则更新list1的name1

    以下是使用旧java的代码:

      for(Object1 obj1:list1) {
        for(Object2 obj2:list2) {
          if(obj1.getId1.equals(obj2.getId2)) {
            obj1.setName1(obj2.getName2);
          }
       }
    }
    

    使用java.util.stream实现这一点的最佳方法是什么?

    流的概念是它没有上下文。知道您在第一个流中的位置是您需要在第二个流中查找对应项的上下文

    使用带有索引
    i
    的正常
    for
    循环

    for (int i=0; i < list2.size(); i++) {
      Object2 item2 = list2.get(i);
      if (list2.get(i).name != null) {
        list1.get(i).name = item.name;
      }
    }
    
    for(int i=0;i
    为了清楚起见,我认为您的代码旨在执行以下操作:将
    list1
    中每个项目的名称更新为
    list2
    中具有相同ID的任何项目的名称。似乎没有任何内容检查
    list1
    中的项目名称是否为空

    如果这是正确的,那么:

    list2.forEach(obj2 -> list1.stream()
         .filter(obj1 -> obj1.getId().equals(obj2.getId()))
         .forEach(obj1 -> obj1.setName(obj2.getName()));
    
    如果要检查名称是否为空,请在设置名称之前添加新筛选器:

        .filter(Objects::isNull)
    

    正如我在评论中提到的。如果
    id
    是对象的uniqe标识符,则a比a更合适

    因此,您最好处理这样的映射(假设id是整数):

    现在,您可以对第二个列表进行流式处理,并相应地更新地图:

    list2
        .stream()
        .filter(o -> o.getName() != null) // remove null names
        .filter(o -> obj1map.containsKey(o.getId())) // just to make sure
        .forEach(o -> obj1map.get(o.getId()).setName(o.getName()));
    

    目前,您的代码具有二次复杂性。是否确实要检查元素的所有组合,或仅检查其各自列表中相同索引处的元素?
    id
    是否表示对象的唯一标识符?在这种情况下,id作为键的映射比列表更合适。它还将时间复杂度降低到O(n)(对于
    HashMap
    )而不是O(n^2)。Yes id是对象的唯一标识符。
    obj1map = list1.stream().collect(toMap(Object1::getId, Function.identity()));
    
    list2
        .stream()
        .filter(o -> o.getName() != null) // remove null names
        .filter(o -> obj1map.containsKey(o.getId())) // just to make sure
        .forEach(o -> obj1map.get(o.getId()).setName(o.getName()));