2014-11-10 12 views
5

sto cercando per un elegante equivalente di questo pezzo di codice utilizzando flussi di Java 8 di:Creazione di una mappa utilizzando Java8 flussi su una struttura di dati nidificato

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

che uno è un po 'troppo difficile per me che posso Pensa a una combinazione che usa flatMap e Collectors.toMap che implementerebbe la funzionalità desiderata.

compilabile esempio:

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

} 
+1

Sei sicuro che sia 'xs.getA()'? – tkroman

+2

dichiari una 'Mappa ' ma usi 'map.put (b, a)' - cosa intendevi? – assylias

+0

Oh, si. È la mappa . –

risposta

5

come si pensava si può fare con un misto di flatMap e 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)); 

Si noti che questo codice si differenzia dall'originale se ci sono B duplicato: il tuo codice continuerà a sovrascrivere il valore corrispondente mentre questo codice genererà un'eccezione.

+1

L'unico modo per farlo funzionare è il casting del flusso interno su Stream >. Altrimenti ricevo un errore di tipo a collect. –

+1

Con il tuo esempio il codice che ho dato funziona bene senza il cast coinvolto. Non hai dimenticato il '<>' in 'new SimpleEntry <> (...)' per caso? – assylias

+0

Potrebbe essere la versione di Java. L'ho provato su una macchina diversa in cui lo stesso codice funzionava mentre non era sull'altra macchina. –

Problemi correlati