Java 8 Collectors.groupingBy with mapped value to set collecting result to the same set

  • A+
Category:Languages

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.

Question is:

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<>()); 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: