I would like to create an immutable view on the sum of a number (>2) of immutable Guava multisets. The multisets are in a list. I don't want to copy the contents into a new multiset. I could probably use Multisets.sum(Multiset, Multiset)
and reduce my stream of Multisets with it, but it seems a bit wasteful to create a summed multiset for every intermediate step. Is there a better way?
In other words: I want a method similar to Multisets.sum(Multiset, Multiset)
, but then for a list of multisets instead of just two. The signature could be: <T> Multiset<T> sum(List<Multiset<T>>)
.
Actually Multisets.sum(Multiset, Multiset)
is implemented in the way it doesn't copy contents but rather creates a view over two multisets, so in your case looping over list of multisets and copying only final result to a new immutable multiset is fine (overhead from views should not matter for small number of multisets). Using Java 8 you can combine Multiset's sum
with Stream#reduce
:
public <T> Multiset<T> sum(final List<Multiset<T>> multisets)
{
return multisets.stream().reduce(ImmutableMultiset.of(), Multisets::sum);
}
EDIT
However although there'll be no copying involved in approach above, as @LouisWasserman noted most optimal solution (YMMV) could be just accumulate results in new multiset:
public <T> ImmutableMultiset<T> sum(final List<Multiset<T>> multisets)
{
final ImmutableMultiset.Builder<T> builder = ImmutableMultiset.builder();
multisets.forEach(builder::addAll);
return builder.build();
}
Having dedicated view class (see @OliverGregoire's answer) is also an option if needed.