Reputation: 2035
I have already gone through few examples and those did not work for me.
Here is what I am trying to do:
I have a List<SomeClass>
of the following class:
class SomeClass {
String rid;
String name;
...
}
The values in my List
look like this:
SomeClass(1,"apple")
SomeClass(1,"banana")
SomeClass(1,"orange")
SomeClass(2,"papaya")
SomeClass(2,"peaches")
SomeClass(3,"melons")
I want to convert the above List
into a Map<String, Set<String>>
, where key is rid
and value is Set
of name
field.
To solve this using Java Streams
I am using groupingBy
and I could come to below solution:
someClassList
.stream()
.map(SomeClass::getName)
.collect(
Collectors.groupingBy(
SomeClass::getRid, Collectors.toSet()));
But this gives me compilation error. How do I solve this and what is the problem with my approach?
Upvotes: 5
Views: 5589
Reputation: 393781
When you call .map(SomeClass::getName)
on your Stream<SomeClass>
, you get a Stream<String>
. You can't execute collect(Collectors.groupingBy(SomeClass::getRid,...))
on a Stream<String>
(you can only execute it on a Stream<SomeClass>
).
Therefore your map
step is wrong.
You need to pass the Collector
returned by Collectors.mapping()
to Collectors.groupingBy()
in order to map the SomeClass
instances to String
s after they are grouped by getRid
.
Map<String, Set<String>> map =
someClassList.stream()
.collect(Collectors.groupingBy(SomeClass::getRid,
Collectors.mapping(SomeClass::getName,
Collectors.toSet())));
Upvotes: 8
Reputation: 56423
Although not as readable as the groupingBy
collector; you can use the toMap
collector just as well:
myList.stream()
.collect(toMap(SomeClass::getRid, e -> new HashSet<>(singleton(e.getName())),
(l, r) -> {l.addAll(r); return l;}));
Ensure that you have the necessary imports for singleton
and toMap
or you can just use Collectors.toMap(...)
and Collections.singleton(...)
respectively.
Upvotes: 3