【问题标题】:Update property of two objects in list based on matching objects in other list根据其他列表中的匹配对象更新列表中两个对象的属性
【发布时间】:2021-01-07 10:48:52
【问题描述】:

我有两个 Pojo:

class Object1 {

    public Object1(String id) {
        this.id = id;
    }

    private String id;
    private Integer value1;
    private Integer value2;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Integer getValue1() {
        return value1;
    }

    public void setValue1(Integer value1) {
        this.value1 = value1;
    }

    public Integer getValue2() {
        return value2;
    }

    public void setValue2(Integer value2) {
        this.value2 = value2;
    }
}
public class Object2 {

    private String id;
    private Integer value;

    public Object2(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }
}

我有两个这些对象的列表,其中对象具有相同的 ID。我想通过设置两个对象的 ID 匹配的 object2 值字段中的值,根据 l2 中对象的值来设置列表 l1 中对象的 value2。

import java.util.Arrays;
import java.util.List;

public class Main{

    public static void main(String[] args) {

        Object1  o1_1 = new Object1("asdf");
        Object1 o1_2 = new Object1("qwert");
        List<Object1> l1 = Arrays.asList(o1_1, o1_2);

        Object2  o2_1 = new Object2("asdf");
        o2_1.setValue(123);
        Object2 o2_2 = new Object2("qwert");
        o2_2.setValue(456);
        List<Object2> l2 = Arrays.asList(o2_1, o2_2);


        l1.forEach(object1 -> l2.stream()
                .filter(object2 -> object1.getId().equals(object2.getId()))
                .forEach(object2 -> object1.setValue2(object2.getValue())));

    }
}

如何使用 java 流 API 有效地做到这一点?

这个解决方案正确吗? 复杂度是 O(n²) 对吧?有没有更有效的方法?

【问题讨论】:

  • 您已经在使用 Stream API,您期待什么?
  • 都是N的大小列表吗?他们可以根据id 重复吗?
  • 可能提高效率的唯一方法是使用Map 和/或将两个匹配的对象存储为单个 ID 下的某种元组/对类型对象,或者甚至组合两个如果模型允许的话。但那是数据结构优化,而不是算法。
  • 如果您关心性能,您可以将其中一个列表转换为以 ID 为键的查找映射,然后更新另一个列表。它的复杂度为 O(N)。
  • @azro: 只是想检查一下我的解决方案是否正确可以改进

标签: java java-stream


【解决方案1】:

如果您关心性能,可以将其中一个列表转换为以 ID 为键的查找映射,然后更新另一个列表。它的复杂度为 O(N)。

你会像这样创建一个查找地图:

Map<Integer, Object2> map = new HashMap<>();
for (Object2 obj : l2) {
    map.put(obj.getId(), obj);
}

或使用流:

Map<Integer, Object2> map = l2.stream()
      .collect(Collectors.toMap(Object2::getId, obj -> obj));

现在您可以在地图的帮助下遍历第一个列表并使用值更新元素。

l1.stream().forEach(o1 -> o1.setValue2(map.get(o1.getId()).getValue()));

或者,如果Object2 只有idvalue,您甚至可以创建一个map&lt;id, value&gt;

Map<Integer, String> map = new HashMap<>();
for (Object2 obj : list) {
    map.put(obj.getId(), obj.getValue());
}

l1.stream().forEach(o1 -> o1.setValue2(map.get(o1.getId())));

【讨论】:

  • 谢谢 :) 我可能会接受这个答案,我只是在等待有关我的解决方案的更多反馈(它是否正确以及我的解决方案的时间复杂度是多少 - O(n²)对吗?)
猜你喜欢
  • 1970-01-01
  • 2019-12-13
  • 1970-01-01
  • 2021-08-10
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多