如何将List <Obj1>转换为Map <Obj1.prop,List <Obj1.otherProp>

Cal*_*ter 3 java java-8 java-stream

如何使用流将列表转换为列表地图?

我想转换List<Obj>Map<Obj.aProp, List<Obj.otherProp>>,
不仅List<Obj>Map<Obj.aProp, List<Obj>>

class Author {
    String firstName;
    String lastName;
    // ...
}

class Book {
    Author author;
    String title;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这是我想要转换的列表:

List<Book> bookList = Arrays.asList(
        new Book(new Author("first 1", "last 1"), "book 1 - 1"),
        new Book(new Author("first 1", "last 1"), "book 1 - 2"),
        new Book(new Author("first 2", "last 2"), "book 2 - 1"),
        new Book(new Author("first 2", "last 2"), "book 2 - 2")
);
Run Code Online (Sandbox Code Playgroud)

我知道怎么做:

// Map<Author.firstname, List<Book>> map = ...
Map<String, List<Book>> map = bookList.stream()
    .collect(Collectors.groupingBy(book -> book.getAuthor().getFirstName()));
Run Code Online (Sandbox Code Playgroud)

但是我能做些什么才能获得:

// Map<Author.firstname, List<Book.title>> map2 = ...
Map<String, List<String>> map2 = new HashMap<String, List<String>>() {
    {
        put("first 1", new ArrayList<String>() {{
            add("book 1 - 1");
            add("book 1 - 2");
        }});
        put("first 2", new ArrayList<String>() {{
            add("book 2 - 1");
            add("book 2 - 2");
        }});
    }
}; 

// Map<Author.firstname, List<Book.title>> map2 = ...
Map<String, Map<String, List<String>> map2 = bookList.stream(). ...
                                                                ^^^
Run Code Online (Sandbox Code Playgroud)

Era*_*ran 7

用于Collectors.mapping将每个映射Book到其对应的标题:

Map<String, List<String>> map = bookList.stream()
    .collect(Collectors.groupingBy(book -> book.getAuthor().getFirstName(),
                                   Collectors.mapping(Book::getTitle,Collectors.toList())));
Run Code Online (Sandbox Code Playgroud)