I have a MultiMap from guava library
Multimap<Integer,String> maps = ArrayListMultimap.create();
maps.put(1, "foo");
maps.put(1, "bar");
maps.put(1, "foo");
maps.put(2, "Hello");
maps.put(2, "foo");
maps.put(2, "World");
maps.put(2, "World");
In this for the key 1, I need to return value which has the highest occurrence. In the above case, it has to return map as
Expected Result:
[1,foo]
[2,World]
I tried
Stream result1 = maps.keySet().stream()
.map(i ->
maps.get(i).stream()
.collect(
Collectors.groupingBy(v -> v, Collectors.counting())
)
);
Result:
{{bar=1, foo=2}=1, {Hello=1, foo=1, World=2}=1}
This is not going to be very strait-forward. You first need to group by key, obviously. Then based on that Key
you need to find the max occurrences of the corresponding Value
(for 1 == foo
, for example). The only way to find that max
is to traverse the Collection<String>
that is mapped to a certain key. This complicates things even more since you use a Multimap
and you could easily have things like:
maps.put(1, "foo");
maps.put(1, "bar");
maps.put(1, "bar");
maps.put(1, "foo");
As such, IMO, this could be written as:
Map<Integer, List<String>> result =
maps.keySet()
.stream()
.collect(Collectors.toMap(
Function.identity(),
x -> {
Map<String, Long> freqMap = maps.get(x)
.stream()
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting())
);
long max = Collections.max(freqMap.values());
return freqMap.entrySet()
.stream()
.filter(y -> y.getValue() == max)
.map(Entry::getKey)
.collect(Collectors.toList());
}
));
Key
(1
and 2
)Collection<String>
that is mapped to that KeyMap<String, Long>
that represents the frequency of values. For example : ["foo" = 2]; ["bar" = 1]
["foo" = 2]; ["bar" = 2]
, for the same Key
, so we need to take both foo
and bar
as the result.max
, I find out the corresponding values.