I'm learning Java 8 - Java 11 and I got a code that I'm converting to java-streams. I have the following classes:
class Resource {
List<Capability> capabilities;
}
class Capability {
String namespace;
Map<String, Object> attributes;
}
I have a stream of Resources and I want to extract all its capabilities attributes from two different namespaces ("a", "b") to a Map<Resource, Map<String, Object>>
that I have sure that do not have duplicates keys.
I did many attempts using map, flatMap but with those, I can't keep a reference of the main resource object. Using the new feature of java9 I could progress, but I'm stuck on the code below where I was able to return all attributes, but in a set. I was not able yet to filter by a capability namespace and also put them in a map:
Map<Resource, Set<Object>> result = pResolved.stream()
.collect(groupingBy(t -> t, flatMapping(
resource -> resource.getCapabilities(null).stream(),
flatMapping(
cap -> cap.getAttributes().entrySet().stream(),
toSet()))));
Seems that I'm on the right path.
There is a way using only java-8 methods as well:
Map<String, Set<Object>> result = pResolved.stream()
.map(Resource::getCapabilities) // Stream<List<Capability>>
.flatMap(List::stream) // Stream<Capability>
.collect(Collectors.toMap( // Map<String, Set<Object>>
c -> c.getNamespace(), // Key: String (namespace)
i -> new HashSet<>(i.getAttributes().values()))); // Value: Set of Map values
Let's assume the sample input is:
Resource [capabilities=[
Capability [namespace=a, attributes={a1=aa1, a2=aa2, a3=aa3}]]]
Resource [capabilities=[
Capability [namespace=b, attributes={b2=bb2, b3=bb3, b1=bb1}],
Capability [namespace=c, attributes={c3=cc3, c1=cc1, c2=cc2}]]]
Then the code above would result in:
a: [aa1, aa3, aa2]
b: [bb1, bb3, bb2]
c: [cc1, cc3, cc2]
You could instead use Collectors.toMap
as the downstream
:
Map<Resource, Map<String, Object>> result = pResolved
.stream()
.collect(groupingBy(Function.identity(),
flatMapping(resource -> resource.getCapabilities().stream(),
flatMapping(cap -> cap.getAttributes().entrySet().stream(),
toMap(Map.Entry::getKey, Map.Entry::getValue)))));
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