I have two objects like following:
public class A {
private Integer id;
private String name;
private List list;
public A(Integer id
Assuming class A
has a copy constructor that effectively copies the List list
attribute and a method that merges two instances of A
:
public A(A another) {
this.id = another.id;
this.name = another.name;
this.list = new ArrayList<>(another.list);
}
public A merge(A another) {
list.addAll(another.list):
return this;
}
You could achieve what you want as follows:
Map result = listOfA.stream()
.collect(Collectors.toMap(A::getId, A::new, A::merge));
Collection result = map.values();
This uses Collectors.toMap, which expects a function that extracts the key of the map from the elements of the stream (here this would be A::getId
, which extracts the id
of A
), a function that transforms each element of the stream to the values of the map (here it would be A::new
, which references the copy constructor) and a merge function that combines two values of the map that have the same key (here this would be A::merge
, which is only called when the map already contains an entry for the same key).
If you need a List
instead of a Collection
, simply do:
List result = new ArrayList<>(map.values());