使用"id"字段更新列表的子部分

Jco*_*cov 8 java lambda list java-8 java-stream

我正在尝试学习如何使用lambda函数获得更时尚的代码,但努力使这项工作成功.

我有两个清单."旧"列表总是比"更新列表"更短或相同.我想从"更新列表"中取出对象,并在较短的"旧列表"中覆盖"陈旧对象".列表具有每个对象的唯一字段.

例如,它有点像使用新版本更新库中的书籍.UUID(标题+作者)保持不变,但新对象用新书/对象替换旧架子上的旧对象.

我知道我可以做到"漫长的道路"然后做一个HashMap<MyUniqueFieldInMyObject, MyObject>然后采取新的List<MyUpdatedObjects>做同样的事情.

即,具有HashMap<UniqueField, MyOldObject>HashMap<UniqueField, MyUpdatedObject>,然后遍历与伪"如果更新的对象具有相同键的条目,覆盖更新后的值的价值"的老物件...

但...

使用功能性lambda语句有没有"更好"的短路方式?

我在思考:

List<MyObject> updatedList;
List<MyObject> oldList;

updatedList.forEach(MyObject -> {

    String id = MyObject.getId();

    if (oldList.stream().anyMatcher(MyObject -> 
        MyObject.getId().matches(id)) {
           //Do the replacement here? If so...how?
       }
}
Run Code Online (Sandbox Code Playgroud)

哪个是我丢失的地方!

谢谢你的指导.

Mis*_*sha 2

如果您想就地更新列表而不是创建新列表,您可以使用List.replaceAll

oldList.replaceAll(old -> 
    updateListe.stream()
        .filter(updated -> updated.getId().equals(old.getId())
        .findFirst()
        .orElse(old)
);
Run Code Online (Sandbox Code Playgroud)

该解决方案的主要问题是其复杂度为 O(size-of-old*size-of-updated)。您描述为“漫长的道路”的方法可以保护您不必为旧列表中的每个条目迭代整个更新列表:

// note that this will throw if there are multiple entries with the same id
Map<String, MyObject> updatedMap = updatedList.stream()
                                         .collect(toMap(MyObject::getId, x->x));

oldList.replaceAll(old -> updatedMap.getOrDefault(old.getId(), old));
Run Code Online (Sandbox Code Playgroud)