2015-06-16 64 views
7

我有這個簡單的bean類:映射列表,以地圖的Java 8個流和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; 
} 

} 

在我的主類,我添加了一些信息列表:

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

現在我要書列表轉換爲地圖這種形式:

Map<String, List<String>> 

使輸出(上面的地圖)是這樣的:

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

所以,我需要將條目按isbn作爲鍵和作者分組。一個isbn可以有多個作者。

我試圖象下面這樣:

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

豆的格式不能更改。如果這個bean具有字符串值而不是map,我可以做到這一點,但堅持使用地圖。

我已經寫了傳統的java 6/7做正確的方法,但試圖通過Java 8的新功能來做到這一點。感謝幫助。

回答

9

你可以做這樣的:

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

Stream<Book>,與每個地圖包含讓您有一個Stream<Entry<String, String>>流你平面地圖吧。從那裏你按照條目的鍵對這些元素進行分組,並將每個條目映射到你收集到值的列表中的值。

+0

完美!這工作。 – daman