Objects are used in example are from package org.jsoup.nodes
import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
I need group attributes by key with resulting value Set
.
Optional<Element> buttonOpt = ...;
Map<String, Set<String>> stringStringMap =
buttonOpt.map(button -> button.attributes().asList().stream()
.collect(groupingBy(Attribute::getKey,
mapping(attribute -> attribute.getValue(), toSet()))))
.orElse(new HashMap<>());
It seems collected correctly, but value all the time is single string (because of library implementation) that contains different values split by space. Trying to improve solution:
Map<String, Set<HashSet<String>>> stringSetMap = buttonOpt.map(
button -> button.attributes()
.asList()
.stream()
.collect(groupingBy(Attribute::getKey,
mapping(attribute ->
new HashSet<String>(Arrays.asList(attribute.getValue()
.split(" "))),
toSet()))))
.orElse(new HashMap<>());
In result i've got different structure Map<String, Set<HashSet<String>>>
but i need Map<String, Set<String>>
I've checked some collectors but have not managed my issue.
How to merge all sets that related to the same attribute key?
You can split your attributes with flatMap
and create new entries to group:
Optional<Element> buttonOpt = ...
Map<String, Set<String>> stringStringMap =
buttonOpt.map(button ->
button.attributes()
.asList()
.stream()
.flatMap(at -> Arrays.stream(at.getValue().split(" "))
.map(v -> new SimpleEntry<>(at.getKey(),v)))
.collect(groupingBy(Map.Entry::getKey,
mapping(Map.Entry::getValue, toSet()))))
.orElse(new HashMap<>());