首页 > 解决方案 > java 8根据属性比较2个列表

问题描述

我必须比较两个列表(list1 到 list2)上的元素,当元素与 code 属性的元素匹配时,我必须用 tobereplace 属性的值替换。

在 list1 我有

[{code:"1", name:"first name", tobereplace: ""} , {code:"2", name:"first name1", tobereplace: ""}, 
{code:"3", name:"first name2", tobereplace: ""}, {code:"4", name:"first name3", tobereplace: ""}]

在 List2 我有:

[{code:"1", name:"first name", tobereplace: ""} , {code:"2", name:"first name1", tobereplace: "" }, 
{code:"3", name:"first name2", tobereplace: ""}, {code:"4", name:"first name3", tobereplace: "this should come in list1"}]

理想情况下,List1 应该具有 List2 的值;我们如何使用 Java8 流来实现这一点

标签: javalistjava-8comparejava-stream

解决方案


假设该类已命名Foo并且要更改的字段String valueToReplace 使用 getter/setter,您可以这样使用listOne.replaceAll()

list1.replaceAll(one ->  list2.stream()
                              .filter(other -> other.getCode().equals(one.getCode())
                              .findAny()
                              .map(Foo::getValueToReplace)
                              .ifPresent( newValue -> one.setValueToReplace(newValue));
                        return one;
                )

这个想法是为list1你的每个元素用第一个匹配的值替换valueToReplace它的字段list2。否则你什么都不做。
这段代码效率不高,但对于小列表来说它是完美的。
对于更大的列表,非常欢迎 使用 aMap来存储。code/valueToReplace

// supposing that the code are unique in each list
Map<Integer, String>  mapOfValueToReplaceByCode =
    list2.stream()
         .collect(toMap(Foo::getCode, Foo::getValueToReplace));

list1.replaceAll(one -> {
                 String newValue = mapOfValueToReplaceByCode.get(one.getCode());
                 if (newValue != null){ 
                     one.setValueToReplace(newValue);
                 }
                  return one;
                )

推荐阅读