Mapping a list to Map Java 8 stream and groupingBy

12,348

You could do it like this:

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

From the Stream<Book>, you flat map it with the stream of each map it contains so that you have a Stream<Entry<String, String>>. From there you group the elements by the entries' key and map each entry to its value that you collect into a List for the values.

Share:
12,348
daman
Author by

daman

Updated on June 03, 2022

Comments

  • daman
    daman almost 2 years

    I have this simple Bean class:

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

    In my main class, I have added some information to the List:

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

    Now I want to convert the books List to a map of this form:

    Map<String, List<String>>
    

    So that the output (the map above) is like:

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

    So, I need to group the entries by isbn as key and authors as values. One isbn can have multiple authors.

    I am trying like below:

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

    The format of the bean cannot be changed. If the bean had string values instead of map, I am able to do it, but stuck with the map.

    I have written the traditional java 6/7 way of doing it correctly, but trying to do it via Java 8 new features. Appreciate the help.