简体   繁体   English

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

[英]Iterate and Map two lists in java 8

I have 2 lists: 我有2个清单:

  1. List1: Object1 (name1, id1) List1:Object1(name1,id1)
  2. List2: Object2(name2, id2) List2:Object2(name2,id2)

Given the size of list1 is the same as list2 鉴于list1的大小与list2相同

I want to iterate ove the list2 and if the name2 of list2 is not null than update the name1 of list1. 我想迭代list2,如果list2的name2不为null,则更新list1的name1。

here is the code using old java: 这是使用旧java的代码:

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

Which is the best way to implement this with java.util.stream? 哪个是用java.util.stream实现这个的最好方法?

Just to be clear, I think your code is intended to do the following: update the name of each item in list1 to be the name of any item in list2 that has the same ID. 为了清楚起见,我认为您的代码旨在执行以下操作:将list1中每个项目的名称更新为list2中具有相同ID的任何项目的名称。 There doesn't seem to be anything checking if the names of items in list1 are null. 似乎没有检查list1中的项名称是否为空。

If that's correct, then: 如果这是正确的,那么:

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

If you want to check if name is null, then add a new filter before setting the name: 如果要检查name是否为null,请在设置名称之前添加新过滤器:

    .filter(Objects::isNull)

As I mentioned in the comments. 正如我在评论中提到的那样。 If the id is a uniqe identifier for your objects, then a Map is more appropriate than a List . 如果id是对象的uniqe标识符,则MapList更合适。

So you better work on such a map (assuming id is an integer): 所以你最好在这样的地图上工作(假设id是一个整数):

Map<Integer, Object1> obj1map;

You could create that map from your first list with 您可以使用第一个列表创建该地图

obj1map = list1.stream().collect(toMap(Object1::getId, Function.identity()));

Now you can stream over your second list and update the map accordingly: 现在,您可以流式传输第二个列表并相应地更新地图:

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

The idea of a stream is that it does not have context. 流的想法是,它没有上下文。 Knowing where you are in the first stream is context which you would need to find the corresponding item in the second stream. 知道您在第一个流中的位置是您需要在第二个流中找到相应项的上下文。

Use a normal for loop with an index i instead. 使用带索引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;
  }
}

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

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