How to merge two list of POJOS using stream JAVA 8 modifying some values when necessary

pburgov :

Hope you can help me. I'll try to make myself clear about the title of the question. I have one POJO like this

public class Factor {
    private int id;
    private String item;
    private int unitId;
    private Double factor;

    // constructor getters and setters
}

I have two List of this class with data from two different tables in two different DB.

The equalsmethod is defined this way

import com.google.common.base.Objects;
//....
@Override
public boolean equals( Object o ) {
    if ( this == o )
        return true;
    if ( o == null || getClass() != o.getClass() )
        return false;
    Factor that = (Factor) o;
    return getUnitId() == that.getUnitId() &&
               Objects.equal(getItem(), that.getItem());
}

so two objects are considered equals when they have the same item and unitId attributes.

Let's say I have these two list:

List<Factor> listA = new ArrayList<>();
listA.add(new Factor(1, "Item1", 1, 0.5));
listA.add(new Factor(2, "Item1", 2, 0.6));
listA.add(new Factor(3, "Item2", 1, 1.0));
listA.add(new Factor(4, "Item3", 1, 2.0));

List<Factor> listB = new ArrayList<>();
listB.add(new Factor(0, "Item1", 1, 0.8));
listB.add(new Factor(0, "Item1", 2, 0.9));
listB.add(new Factor(0, "Item4", 1, 1.0));
listB.add(new Factor(0, "Item5", 1, 2.0));

Taking the equalsmethod into account, the first two elements of the lists should be considered equals.

The reason why the ids in the B list are all 0, is because that table has not an id field.

What I'm trying to achieve is to create a new list by merging these two lists, but if the objects are equals, it should take the id from listA and the factor from listB.

In this way, the result list would have the following objects

(1, "Item1", 1, 0.8)
(2, "Item1", 2, 0.9)
(0, "Item4", 1, 1.0)
(0, "Item5", 1, 2.0)

I know how to compare both list with stream and filter which objects are equals or different but does anybody know how to get a new object combining the equals?

Adrian :

assuming that you also have overridden hashCode method you can use toMap collector:

Collection<Factor> values = Stream.concat(listA.stream(), listB.stream())
            .collect(Collectors.toMap(Function.identity(), 
                                      Function.identity(), (a, b) -> {
        return new Factor(a.getId(), a.getItem(), a.getUnitId(), b.getFactor());
    })).values();

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=105895&siteId=1