dfsg76
dfsg76

Reputation: 524

Update property of two objects in list based on matching objects in other list

I have two Pojos:

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;
    }
}

I have two lists of these objects where the objects have the same Id. I want to set value2 of the Objects in the list l1 based on the value of the objects in l2 by setting the value from the object2 value field where the Ids of both objects match.

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

    }
}

How would I do that efficiently with the java stream API?

Is this solution correct? The complexity is O(n²) right? Is there a more efficient way?

Upvotes: 0

Views: 988

Answers (1)

Amongalen
Amongalen

Reputation: 3131

If you care about performance, you could convert one of the lists to a lookup map with ID as a key and then update the other list. It would have a complexity of O(N).

You would create a lookup map like so:

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

Or with Streams:

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

Now you can iterate over first list and update elements with value with help of the map.

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

Alternatively, if Object2 only has id and value, you could even create a map<id, value>:

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

Upvotes: 1

Related Questions