使用流将实体结构映射到地图的映射

时间:2016-06-09 20:39:31

标签: java java-stream collectors

我有实体:

public class Library {
  String name;
  Set<Book> books;
}

public class Book {
  String isbn;
  String title;
}

现在我需要一个

Map<String, Map<String, Book>> mapByLibraryNameAndIsbn;

其中第一个Map的密钥是Library的名称,第二个Map的密钥是Book的isbn。

为此,我想使用java流和一些收集器。我尝试使用groupingBy和toMap,但取得了任何成功。

更新1:

到目前为止我试过了

Map<String, List<Book>> libraryList.stream().collect(groupingBy(l -> l.getName(), toList()));

但我刚收到MapList

有什么想法吗? TIA!

2 个答案:

答案 0 :(得分:4)

由于您从List<Library>开始,您可能希望将Collectors.toMap()与两个映射函数结合使用:

  1. 图书馆 - &gt;键的字符映射器(返回name
  2. 图书馆 - &gt;映射映射器的值。
  3. 对于第二个映射器,您可能希望流式传输Set个图书,将它们收集到Map类似于&#39;外部的图书中。 map,再次使用2个(不同的)映射函数:

    1. 一本书 - &gt;键的字符映射器(返回isbn
    2. 值的身份映射器(返回书本身)。
    3. 类似于:

      List<Library> libs;
      // populate the libraries
      Map<String,Map<String,Book>> map = libs.
          stream().
          collect(Collectors.toMap(l -> l.name, l -> {
              return l.books.
                  stream().
                  collect(Collectors.toMap(b -> b.isbn, Function.identity()));  
          }));
      

      列出库;

答案 1 :(得分:2)

使用方法引用和静态导入:

import static java.util.stream.Collectors.toMap;

Map<String, Map<String, Book>> map = libs.stream().collect(
        toMap(Library::getName, 
                l -> l.getBooks().stream().collect(
                        toMap(Book::getIsbn, b -> b))));