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

时间:2016-02-15 11:40:15

标签: java

我有2个名单:

  1. List1:Object1(name1,id1)
  2. List2:Object2(name2,id2)
  3. 鉴于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实现此功能的最佳方法是什么?

3 个答案:

答案 0 :(得分:11)

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

如果这是正确的,那么:

list2.forEach(obj2 -> list1.stream()
     .filter(obj1 -> obj1.getId().equals(obj2.getId()))
     .forEach(obj1 -> obj1.setName(obj2.getName()));

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

    .filter(Objects::isNull)

答案 1 :(得分:3)

正如我在评论中提到的那样。如果id是对象的唯一标识符,那么MapList更合适。

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

Map<Integer, Object1> obj1map;

您可以使用

从第一个列表创建该地图
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()));

答案 2 :(得分:-3)

流的想法是有上下文。知道你在第一个流中的位置是你需要在第二个流中找到相应项的上下文。

使用带有索引for的普通i循环。

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