Creating a map using Java8 streams in a nested data structure

I am looking for the elegant equivalent of this code snippet using Java 8 threads:

Collection<X> xs = ...; Map<B, A> map = new SomeMap<>(); for (X x : xs) { A a = x.getA(); Collection<B> bs = x.getBs(); for (B b : bs) map.put(b, a); } 

This is too complicated for me, because I cannot come up with a combination using flatMap and Collectors.toMap, which will implement the desired functionality.

Compiled Example:

 import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; public class Application { public static class A {} public static class B {} public static class X { private A a; private Collection<B> bs; public X(A a, Collection<B> bs) { this.a = a; this.bs = bs; } public A getA() { return a; } public Collection<B> getBs() { return bs; } } public static void main(String[] args) { X x1 = new X(new A(), Arrays.asList(new B(), new B())); X x2 = new X(new A(), Arrays.asList(new B())); Collection<X> xs = Arrays.asList(x1, x2); Map<B, A> map = new HashMap<>(); for (X x : xs) { A a = x.getA(); Collection<B> bs = x.getBs(); for (B b : bs) map.put(b, a); } } } 
+5
source share
1 answer

As you thought, you can do this with a mixture of flatMap and toMap:

 Map<B, A> map = xs.stream() .flatMap(x -> x.getBs().stream() .map(b -> new SimpleEntry<> (b, x.getA()))) .collect(toMap(Entry::getKey, Entry::getValue)); 

Note that this code is different from your original if there are duplicates of Bs: your code will overwrite the corresponding value, while this code throws an exception.

+5
source

Source: https://habr.com/ru/post/1206575/


All Articles