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?
With Java 8, you can convert a List to Map in one line using the stream() and Collectors. toMap() utility methods. The Collectors. toMap() method collects a stream as a Map and uses its arguments to decide what key/value to use.
Converting a list to stream is very simple. As List extends the Collection interface, we can use the Collection. stream() method that returns a sequential stream of elements in the list.
stream(). mapToInt(AClass::getValue).
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())));
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With