2015-06-16 2 views
7

ho questa semplice classe Bean:Mappare un elenco per Mappa Java 8 torrente e groupingBy

public class Book {  

public Book(Map<String, String> attribute) { 
    super(); 
    this.attribute = attribute; 
} 
//key is isbn, val is author 
private Map<String, String> attribute; 

public Map<String, String> getAttribute() { 
    return attribute; 
} 
public void setAttribute(Map<String, String> attribute) { 
    this.attribute = attribute; 
} 

} 

Nella mia classe principale, ho aggiunto alcune informazioni a elenco:

Map<String, String> book1Details = new HashMap<String, String>(); 
    book1Details.put("1234", "author1"); 
    book1Details.put("5678", "author2"); 
    Book book1 = new Book(book1Details); 

    Map<String, String> book2Details = new HashMap<String, String>(); 
    book2Details.put("1234", "author2"); 
    Book book2 = new Book(book2Details); 

    List<Book> books = new ArrayList<Book>(); 
    books.add(book1); 
    books.add(book2); 

Ora vogliono convertire l'elenco di libri a una mappa di questa forma:

Map<String, List<String>> 

modo che l'uscita (la mappa qui sopra) è come:

//isbn: value1, value2 
1234: author1, author2 
5678: author1 

Quindi, ho bisogno di raggruppare le voci per isbn come chiave e gli autori come valori. Un isbn può avere più autori.

Sto provando come di seguito:

Map<String, List<String>> library = books.stream().collect(Collectors.groupingBy(Book::getAttribute)); 

Il formato del chicco non può essere modificato. Se il bean avesse valori stringa invece di mappa, sono in grado di farlo, ma bloccato con la mappa.

Ho scritto il metodo tradizionale di java 6/7 per farlo correttamente, ma provando a farlo tramite Java 8 nuove funzionalità. Apprezzo l'aiuto.

risposta

9

Si potrebbe fare così:

Map<String, List<String>> library = 
    books.stream() 
     .flatMap(b -> b.getAttribute().entrySet().stream()) 
     .collect(groupingBy(Map.Entry::getKey, 
          mapping(Map.Entry::getValue, toList()))); 

Dal Stream<Book>, mappa piatta voi con il flusso di ogni mappa si contiene in modo da avere un Stream<Entry<String, String>>. Da lì puoi raggruppare gli elementi con la chiave delle voci e mappare ciascuna voce al suo valore che raccogli in un elenco per i valori.

+0

Perfetto! Questo funziona. – daman