Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Agregate nested list with Stream api

Let's say I have a Shelf class and each Shelf has multiple Books.

public class Shelf{
   private String shelfCode;
   private ArrayList<Book> books; //add getters, setters etc.
}

public class Book{
  private String title;
}

Now, let's say from some method I have a List of Shelfs, each containing some books. How do I use stream to collect all the books to this list?

List<Shelf> shelves = new ArrayList<Shelf>();

Shelf s1 = new Shelf();
s1.add(new Book("book1"));
s1.add(new Book("book2"));

Shelf s2 = new Shelf();
s1.add(new Book("book3"));
s1.add(new Book("book4"));

shelves.add(s1);
shelves.add(s2);

List<Book> booksInLibrary = //??

I'm thinking something like

List<Book> booksInLibrary = 
      shelves.stream()
             .map(s -> s.getBooks())
             .forEach(booksInLibrary.addall(books));

but it doesn't seem to work, throwing a compilation error.

like image 213
bryan.blackbee Avatar asked Mar 22 '18 08:03

bryan.blackbee


People also ask

How do you flatten a stream list?

Create an empty list to collect the flattened elements. With the help of forEach loop, convert each elements of the list into stream and add it to the list. Now convert this list into stream using stream() method. Now flatten the stream by converting it into list using collect() method.

Which operations perform aggregation in stream?

Aggregate operations − Stream supports aggregate operations like filter, map, limit, reduce, find, match, and so on. Pipelining − Most of the stream operations return stream itself so that their result can be pipelined.

What are the advantages of Stream API over collections API?

The stream API allows you to perform operations on collections without external iteration. In this case, we're performing a filter operation which will filter the input collection based on the condition specified.


1 Answers

You can use flatMap for this

shelves.stream()
       .flatMap(s -> s.getBooks().stream())
       .collect(Collectors.toList());

The streaming process is quite simple : s -> s.getBooks().stream() makes a stream for each book on each shelf, flatMap flattens everything, and collect(Collectors.toList()) stores the result in a list.

like image 123
Kepotx Avatar answered Sep 18 '22 07:09

Kepotx