How can I reduce the Map<X, List<String>>
grouping by the X.p and join all the list values at the same time, so that I have Map<Integer, List<String>>
at the end?
This is what I've tried so far:
class X {
int p;
int q;
public X(int p, int q) { this.p = p; this.q = q; }
}
Map<X, List<String>> x = new HashMap<>();
x.put(new X(123,5), Arrays.asList("A","B"));
x.put(new X(123,6), Arrays.asList("C","D"));
x.put(new X(124,7), Arrays.asList("E","F"));
Map<Integer, List<String>> z = x.entrySet().stream().collect(Collectors.groupingBy(
entry -> entry.getKey().p,
mapping(Map.Entry::getValue,
reducing(new ArrayList<>(), (a, b) -> { a.addAll(b); return a; }))));
System.out.println("z="+z);
But the result is: z={123=[E, F, A, B, C, D], 124=[E, F, A, B, C, D]}.
I want to have z={123=[A, B, C, D], 124=[E, F]}
Here's one way to do it using two Stream pipelines :
Map<Integer, List<String>> z =
// first process the entries of the original Map and produce a
// Map<Integer,List<List<String>>>
x.entrySet()
.stream()
.collect(Collectors.groupingBy(entry -> entry.getKey().p,
mapping(Map.Entry::getValue,
toList())))
// then process the entries of the intermediate Map and produce a
// Map<Integer,List<String>>
.entrySet()
.stream()
.collect (toMap (Map.Entry::getKey,
e -> e.getValue()
.stream()
.flatMap(List::stream)
.collect(toList())));
Java 9 is supposed to add a flatMapping Collector, that would make your life easier (I learned about this new feature thanks to Holger).
Output :
z={123=[A, B, C, D], 124=[E, F]}
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