Reputation: 5423
I have this class:
class A{
int count=0;
//equals and hashCode implemented
}
create two collections:
Collection<A> collection1;//something
Collection<A> collection2;//something
concatenate the collections:
Stream.concat(collection1.stream(), collection2.stream())
//do something here???
.distinct()
.sorted(new Comparator<A>() {
@Override
public int compare(A o1, A o2) {
return new Integer(o1.count).compareTo(new Integer(o2.count));
}
})
.collect(Collectors.toList());
I want to merge these two lists and if there any duplicates, I want to update integer count;
the above code gets rid of duplicates completely
For example,
say we got an object in both collection1 and collection2 that are equal (o1.equals(o2) == true)
. One has count=10
and the other one has count=20
I want to have a collection of distinct objects with that object to have count=30
Is there a way of doing it?
Upvotes: 1
Views: 469
Reputation: 56433
You can't do it with your current approach, instead you can use the toMap
collector:
Stream.concat(collection1.stream(), collection2.stream())
.collect(Collectors.toMap(Function.identity(),Function.identity(),
(left, right) -> {
left.setCount(left.getCount() + right.getCount());
return left;
})).values()
.stream()
.sorted(Comparator.comparingInt(A::getCount))
.collect(Collectors.toList());
This uses Stream.concat to merge collection1
and collection2
together into a single Stream<A>
.
We then call the toMap collector where the first Function.identity() selects the elements of the source as the keys i.e A
and the second Function.identity() also selects the elements of the source as the values; again A
, so at this point, you can visualise the data as Map<A, A>
.
The function (left, right) -> { ... }
is known as the merge function, this is the place where if two given objects are equal we then say take the count of the first element and take the count of the second element, add them together and assign the new value back to one of the elements we are going to keep and then discard the other.
because you've overridden equals
and hashcode
, we don't need to explicitly call it, instead, the equals
method will be called implicitly to determine if two given objects are equal.
once we've collected the elements to a Map<A, A>
, we then call the values()
method to retrieve a Collection<A>
, this then enables us to create a stream from it with the stream()
method and further enables us to sort the streams elements with the sorted method and finally collect it to a List<A>
with the toList collector.
Upvotes: 3