I have a class similar to the below MyObject
.
public class MyObject {
private String key; // not unique. multiple objects can have the same key.
private boolean isPermanent;
private double value1;
private double value2;
public MyObject merge(MyObject m){
value1 += m.getValue1();
value2 += m.getValue2();
return this;
}
// getters, setters and constructors...
}
Following is the sample data:
List<MyObject> objs = new ArrayList<>();
objs.add(new MyObject("1", false, 100, 200));
objs.add(new MyObject("2", false, 300, 100));
objs.add(new MyObject("1", false, 200, 300));
objs.add(new MyObject("3", true, 100, 200));
objs.add(new MyObject("1", true, 500, 100));
objs.add(new MyObject("1", true, 100, 100));
I want to combine these objects based on isPermanent
and key
and did the following:
(Note that I have added import static java.util.stream.Collectors.*
to import groupingBy
, partitioningBy
and reducing
in the below code)
objs.stream()
.collect(partitioningBy(MyObject::isPermanent,
groupingBy(MyObject::getKey,
reducing(new MyObject(), MyObject::merge))));
The returned map is of type Map<Boolean, Map<String, MyObject>>
.
I am expecting the map returned to be as below (ignoring fields other than value1
and value2
)
{false : { 1 : { 300, 500 } } , { 2 : { 300, 100 } }, true : { 1 : { 600, 200 } } , { 3 : { 100, 200 } } }
But the result I am getting is like:
{false : { 1 : { 1300, 1000 } } , { 2 : { 1300, 1000 } }, true : { 1 : { 1300, 1000 } } , { 3 : { 1300, 1000 } } }
Since I am passing an object as the identity, I believe that the same object is being updated for every group. Since a lambda cannot be passed onto the reduction
method, is there any way to solve this problem?