Reputation: 20090
I asked a question yesterday flattening/grouping a HashMap. I got a great response that suggested I do this.
return new ArrayList<>(map.entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.joining(","))))
.values())
However, I would like my list of comma separated characters to be sorted alphabetically. The comments suggested I try using TreeMap::new
as an argument to groupingBy()
, but when I try this my list of characters remains unsorted:
return new ArrayList<>(map.entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry::getValue,
TreeMap::new,
Collectors.mapping(Map.Entry::getKey, Collectors.joining(","))))
.values())
Below is my original question with a link to the post.
Given mapping of letters to numbers, I would like to return a list of Strings, where each String is a comma delimited list of the letters grouped by their associated number.
For this map
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 4);
map.put("D", 1);
map.put("E", 1);
map.put("F", 2);
I would like to return a List containing:
"A,D,E" "B,F", "C"
Any suggestions how this can be accomplished using the 1.8 streaming functions?
How to flatten and group this HashMap, using streams?
Upvotes: 2
Views: 171
Reputation: 1902
This might also work for you:
return new ArrayList<>(map.entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry::getValue,
TreeMap::new,
Collectors.mapping(Map.Entry::getKey, Collectors.collectingAndThen(Collectors.toList(), l -> {
Collections.sort(l);
return String.join(",", l);
}))))
.values());
Upvotes: 1
Reputation: 31878
Tweaking one of the answers to the linked question, this should do the trick for what you're looking for:
List<String> result = map.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue))
.values().stream()
.map(e -> e.stream()
.map(Map.Entry::getKey)
.sorted() // <<< modified this
.collect(Collectors.joining(",")))
.collect(Collectors.toList());
Upvotes: 0
Reputation: 12463
Turn the map to a TreeMap
before performing the operation, and the keys will be in order in the output.
// * here
return new ArrayList<>(new TreeMap(map).entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry::getValue,
TreeMap::new,
Collectors.mapping(Map.Entry::getKey, Collectors.joining(","))))
.values())
Upvotes: 2