3

How to convert a list to a map of list using stream ?

I want to convert List<Obj> to Map<Obj.aProp, List<Obj.otherProp>>,
not only List<Obj> to Map<Obj.aProp, List<Obj>>

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

class Book {
    Author author;
    String title;
    // ...
}

This is the list I want to transform :

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

I know how to do this :

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

But what can I do to obtain that :

// 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(). ...
                                                                ^^^
Eran
  • 387,369
  • 54
  • 702
  • 768
Calfater
  • 1,255
  • 1
  • 10
  • 19
  • 4
    Possible duplicate of [Group a list of objects by an attribute : Java](https://stackoverflow.com/questions/21678430/group-a-list-of-objects-by-an-attribute-java) – Lino Jun 28 '18 at 09:20

1 Answers1

7

Use Collectors.mapping to map each Book to its corresponding title:

Map<String, List<String>> map = bookList.stream()
    .collect(Collectors.groupingBy(book -> book.getAuthor().getFirstName(),
                                   Collectors.mapping(Book::getTitle,Collectors.toList())));
Eran
  • 387,369
  • 54
  • 702
  • 768