8

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.

1 Answer 1

15

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Indeed, any time you're thinking of using forEach() on a stream, take a step back and ask yourself "is this really the best approach?". Then answer yourself with "ah, of course not".
I think you need to add a map step to your example to get the books property of the Shelf object
Yep, it should be flatMap(s -> s.getBooks().stream())
mkyong.com/java8/java-8-flatmap-example more great examples and good explanations of how flatMap works
yet a slightly different approach using method references --> shelves.stream().map(Shelf::getBooks).flatMap(List::stream) .collect(Collectors.toList());

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.