在java 8中迭代并映射两个列表

you*_*ene 4 java

我有2个清单:

  1. List1:Object1(name1,id1)
  2. List2:Object2(name2,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);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

哪个是用java.util.stream实现这个的最好方法?

spr*_*ter 11

为了清楚起见,我认为您的代码旨在执行以下操作:将每个项目的名称更新为具有相同ID list1的任何项目的名称list2.似乎没有任何东西检查项目的名称list1是否为空.

如果这是正确的,那么:

list2.forEach(obj2 -> list1.stream()
     .filter(obj1 -> obj1.getId().equals(obj2.getId()))
     .forEach(obj1 -> obj1.setName(obj2.getName()));
Run Code Online (Sandbox Code Playgroud)

如果要检查name是否为null,请在设置名称之前添加新过滤器:

    .filter(Objects::isNull)
Run Code Online (Sandbox Code Playgroud)


See*_*ose 5

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

所以你最好在这样的地图上工作(假设 id 是一个整数):

Map<Integer, Object1> obj1map;
Run Code Online (Sandbox Code Playgroud)

您可以从您的第一个列表中创建该地图

obj1map = list1.stream().collect(toMap(Object1::getId, Function.identity()));
Run Code Online (Sandbox Code Playgroud)

现在您可以流式传输您的第二个列表并相应地更新地图:

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