使用流基于另一个列表更新一个列表

时间:2018-08-27 11:58:32

标签: java arraylist lambda java-8 java-stream

我想从传入列表中更新现有列表中的项目。

class Person{
  String id;
  String name;
  String age;
.
.
.
  @Override
  public boolean equals(Object object) {
    return ... ((Person) object).id.equals(this.id);
  }
}

当前列表较短:

ArrayList<Person> currentList = Arrays.asList(
   new Person("0", "A", 25),
   new Person("1", "B", 35)
);

接收到的列表更大,例如

ArrayList<Person> updatedList = Arrays.asList(
       new Person("0", "X", 99),
       new Person("1", "Y", 100),
       new Person("2", "C", 2),
       new Person("3", "D", 3),
       new Person("4", "E", 5)
    );

包括当前列表中的项目(由其 id 标识)。

我想用新列表中的相同项替换当前列表中的所有项。

因此,转换后,当前列表将为

{ Person(0, "X", 99), Person(1, "Y", 100) }

是否只能使用Stream。

4 个答案:

答案 0 :(得分:1)

如果currentList始终是updatedList的子集-意味着所有currentList都将出现在updatedList中,则可以执行以下操作:

Set<String> setOfId = currentList.stream()
                                 .map(person -> person.getId()) // exctract the IDs only
                                 .collect(Collectors.toSet());  // to Set, since they are unique

List<Person> newList = updatedList.stream()                     // filter out those who don't match
                                  .filter(person -> setOfId.contains(person.getId()))  
                                  .collect(Collectors.toList());

如果updatedListcurrentList截然不同-两者都可以拥有唯一的人,则必须进行两次迭代并使用Stream::map来替换Person。如果找不到,请替换为self:

List<Person> newList = currentList.stream()
    .map(person -> updatedList.stream()                                       // map Person to
                              .filter(i -> i.getId().equals(person.getId()))  // .. the found Id
                              .findFirst().orElse(person))                    // .. or else to self
    .collect(Collectors.toList());                                            // result to List

答案 1 :(得分:1)

假设您希望将currentList项目替换为UpdatedList中的对象,则应该可以进行以下操作:

currentList.stream().map((p) -> {
            return updatedList.stream().filter(u -> p.equals(u)).findFirst().orElse(p);
        }).collect(Collectors.toList());

答案 2 :(得分:0)

是的,可以使用流

  1. 从currentList中查找所需的ID列表
  2. 过滤器记录中的ID位于第一个列表中

    List<String> ids = currentList.stream().map(Person::getId).collect(Collectors.toList());
    currentList = updatedList.stream().filter(o -> ids.contains(o.getId()))
                                      .collect(Collectors.toList());
    

答案 3 :(得分:0)

这将满足您的要求。

 Map<String, Person> collect = updatedList
                               .stream()
                               .collect(Collectors.toMap(Person::getId, Function.identity()));

 currentList = currentList
               .stream()
               .map(Person::getId)
               .map(collect::get)
               .collect(Collectors.toList());

正如@Holger所提到的,为一个小的List这样做不是很优雅