Reputation: 10220
I have a map Map<String, Set<String>>
Map<String, Set<String> result = map.entrySet().parallelStream().collect(
Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));
I want to convert it to Map<String, Set<String>>
. by grouping the values and swapping the places of key and value.
But this line gives me
Type mismatch: cannot convert from Map<Object,Set<Object>> to Map<String,Set<String>>
Upvotes: 2
Views: 2697
Reputation: 10220
Just to avoid the confusion, I'm answering my question. Thanks to @AndyTurner @alexrolea for pointing out the solution.
Map<Set<String>, Set<String>> result = map.entrySet().parallelStream()
.collect(
Collectors.groupingBy(entry -> (Set<String>) entry.getValue(),
Collectors.mapping(entry -> entry.getKey(), Collectors.toSet())));
I had to replace Map.Entry::getValue
with entry -> (Set<String>) entry.getValue()
and the other one too.
This helped me group the map by values and use them as keys. Thanks @nullpointer
In fact, this also works. The problem is I was not returning the right datatype.
Map<Set<String>, Set<String>> result = map.entrySet().parallelStream()
.collect(
Collectors.groupingBy(Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));
Upvotes: 1
Reputation: 140309
The problem that you've got here is the type of the map you are creating is:
Map<Set<String>, Set<String>>
not Map<String, Set<String>>
.
As such, you need to expand the map's values first, for example:
Map<String, Set<String>> collect = map.entrySet()
.parallelStream()
// Expand (k, {v1, v2, v3}) to [(v1, k), (v2, k), (v3, k)]
.flatMap(e -> e.getValue().stream().map(ee -> new SimpleEntry<>(ee, e.getKey())))
.collect(
Collectors.groupingBy(
Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toSet())));
Unless you really need the parallel processing, I think it would be much easier to use loops:
Map<String, Set<String>> collect = new HashSet<>();
for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
for (String v : entry.values()) {
collect.computeIfAbsent(v -> new HashSet<>())
.add(entry.getKey()));
}
}
Upvotes: 4
Reputation:
Here is an example considering your initial Map is Object to Object. Adapt as needed.
Map<Object,Object> map = new HashMap<>();
Map<String, Set<String>> result = map
.entrySet()
.parallelStream()
.collect(Collectors.groupingBy(entry -> (String) entry.getKey(),
Collectors.mapping(entry -> (String) entry.getKey(), Collectors.toSet())));
The problem with your code is that Map.Entry::getKey
returns an Object, not a String.
Upvotes: 1