This is best shown by example.
Let's say you have a list of Books as below:
public class Book{ String author; Date published; int copiesSold; String catagory; public String getAuthor() { return author; } public Date getPublished() { return published; } public int getCopiesSold() { return copiesSold; } public String getCatagory() { return catagory; } }
To group them into a map of authors to books used to be a little bit painful but is now a one liner!
Map<String, List<Book>> authorsToBooks = books
.stream()
.collect(Collectors.groupingBy(Book::getAuthor));
The only problem with this that you might have is that the default Map implementation returned is a HashMap which of course is unordered and you might well want to order by the key, in this example by the author. Of course, you could always sort the Map in a second step but there's a way to do it in one line.
To fix that let's introduce this static utility function:
public static <T, K extends Comparable<K>> Collector<T, ?, TreeMap<K, List<T>>> sortedGroupingBy(Function<T, K> function) { return Collectors.groupingBy(function, TreeMap::new, Collectors.toList()); }
We can call it like this:
Map<String, List<Book>> authorsToBooks = books
.stream()
.collect(sortedGroupingBy(Book::getAuthor));
This time the map implementation is a TreeMap which has returned the Map of authors to their books in alphabetical order.