I am searching for an elegant equivalent of this piece of code using Java 8's streams:
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);
}
That one is a bit too tricky for me as I can’t think of a combination using flatMap and Collectors.toMap which would implement the desired functionality.
Compilable 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);
        }
    }
}
                As you thought you can do it 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 differs from your original if there are duplicate Bs: your code will keep overwriting the corresponding value whereas this code will throw an exception.
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