Preparing for Java Interview?

My books Grokking the Java Interview and Grokking the Spring Boot Interview can help

Download PDF

3 Examples of flatMap() of Stream in Java

Hello guys, if you are doing Java development then you must have come across the flatMap() method on Stream and Optional Class. The flatMap() method is extension of map() function as it does both flattening and mapping (or transformation) instead of just transformation done by map() method. I have explained the difference between map() and flatMap() earlier in detail, but just to revise, let's revisit it. If you have a list of String e.g. {"credit", "debit", "master", "visa"} then you can use the map() method to get a list of integer where each value is length of corresponding String e.g. list.stream().map(s -> s.length()) will produce {6, 5, 6, 4}. This is called transformation because you have transformed an stream of String to a Stream of integer


The flatMap() function comes into the picture, when we have two level of nesting e.g. a list of list or a stream of streams. It than flatten the stream of stream to produce stream of values. 

For example, suppose you have list of orders and each order contains list of lineItems, now if you want a list of LineItems for all orders then you can use flatMap() function of Stream class. One more example of flatMap is, suppose, you have a list of states and each state has list of voters, now how do you get all the voters for the country? Well, just use the flatMap() method. 

If these examples still doesn't make much sense to you and you are not able to understand what is flatMap, how it works and when to use flattMap()  in Java then here is my last attempt with a concrete code  examples:

Suppose, I have a list of Books and each book has list of Chapters as shown below:


class Book{
List<Chapters> listOfChapters

...

}


I have 


List<Book> javaBooks = Arrays.asList(new Book[]{book1, book2})


now, I can retrieve list of chapters from this list of books by using the flatMap() method in Java as shown below:


List<String> listOfChapters = listOfBooks.stream()
                           .flatMap(book -> book.getChapters().stream())
                           .collect(Collectors.toList());


You can see the output first to understand what flatpMap() did for you:


list of books : [Effective Java, Clean Code]
list of chapters: [item 1, item 2, chapter 1, chapter 2]


Though, you should not forget to call the stream() method on the list retrieved by getChapters() as flatMap operates on Stream not List. If you want to learn Stream API in Java in depth then you can also see these Java Collections and Stream courses and books to learn more about Stream.flatMap()in Java. 

3 Examples of flatMap() function of Stream in Java




3 Examples of FlatMap function in Java Stream

Here is our sample Java program to demonstrate the usage of flatMap() method in Java 8. I have shown three main examples of flatMap, the first one is used to flatten a list of list which contains String, the second one is used to flatter a list of list which consider integer and third one is used to flatten a list of custom objects, book in our case. 

The third example is the most practical and you will likely to face such kind of scenarios in real world programming.  

But, First let's see our Book class on which we will operate flatMap() function.

Book Class:

class Book{
private List<String> chapters;
private String name;

public Book (String name, List<String> chapters){
this.name = name;
this.chapters = chapters;
}

public List<String> getChapters(){
return chapters;
}

@Override
public String toString() {
return name;
} 


}


And, now see the actual test class which will show you 3 ways to use flatMap() function in Java 8, In first example we have used flatMap with list of String while in second example we have used flatMap with list of integers and in last examples we have used flatMap function and Stream with a list of custom objects so that you know how you can transform and flatten list of both standard Java objects as well as any custom objects you have in your application like User, Employee, Order, Trade, or Book etc.

package test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
* Java Program to demonstrate how to use the flatMap()
* method of Stream class in Java 8. 
*/
public class Test {

public static void main(String[] args) {

// Using flatMap with list of String
List<List<String>> listOfListOfString = new ArrayList<>();
listOfListOfString.add(Arrays.asList("master", "visa"));
listOfListOfString.add(Arrays.asList("flying", "reward"));
listOfListOfString.add(Arrays.asList("apple pay", "samsung pay"));

List<String> listOfJustStrings = listOfListOfString.stream()
.flatMap(list -> list.stream())
.collect(Collectors.toList());
System.out.println("list of cards: " + listOfJustStrings);


// Using flatMap with list of integers
List<List<Integer>> listOfListOfInts = new ArrayList<>();
listOfListOfInts.add(Arrays.asList(2, 4));
listOfListOfInts.add(Arrays.asList(3, 9));
listOfListOfInts.add(Arrays.asList(4, 16));

List<Integer> listOfIntegers = listOfListOfInts.stream()
.flatMap(list -> list.stream())
.collect(Collectors.toList());
System.out.println("list of integers : " + listOfIntegers);


// Using flatMap() with custom objects
Book effectiveJava = new Book("Effective Java", Arrays.asList("item 1", "item 2"));
Book cleanCode = new Book("Clean Code", Arrays.asList("chapter 1", "chapter 2"));

List<Book> listOfBooks = new ArrayList<>();
listOfBooks.add(effectiveJava);
listOfBooks.add(cleanCode);

List<String> listOfChapters = listOfBooks.stream()
.flatMap(book -> book.getChapters().stream())
.collect(Collectors.toList());

System.out.println("list of books : " + listOfBooks);
System.out.println("list of chapters: " + listOfChapters);
}

}


Output

list of cards: [master, visa, flying, reward, apple pay, samsung pay]

list of integers : [2, 4, 3, 9, 4, 16]

list of books : [Effective Java, Clean Code]

list of chapters: [item 1, item 2, chapter 1, chapter 2]


You can see that the final result is flattened, there is no list of list, but just list of values. The Stream class also provides three overloaded version of flatMap() method e.g. the flatMapToInt(), flatMaptoLong() and flatMapToDouble(), to work with long, int, and double primitives' values.  

These are specialized version of flatMap operator which returns IntStream, LongStream and DoubleStream respectively. If you need one of them then you can use these methods for flattening. In general you use specialized Stream like IntStream when you want to avoid the cost of boxing and unboxing between int and Integer and that's why IntStream perform better when you are working with int primitive values. 

That's all about how to use flatMap() in Java 8. The flatMap() method is defined in Stream class of java.util.stream package and its one of the most useful functional operation you have in JDK. It's very useful with Collections and can help to resolve lot of queries as shown in the example in first paragraph. Just remember the difference between map() and flatMap() in Java, former do just transformation, while later does both transformation and flattening.

         
Related Java 8 Lambda and Stream Tutorials you may like
  • How to use peek() method in Java 8 (example)
  • 50 Java 8 Lambda, Stream, and functional interview questions (lambda questions)
  • How to filter Collection using Streams in Java 8 (check here)
  • 15 Spring Data JPA Interview Questions (list)
  • 20 Examples of Date and Time in Java 8 (tutorial)
  • Top 5 Books to Learn Java 8 (read here)
  • How to use filter() method in Java 8 (tutorial)
  • 15 Java Microservice Interview questions (microservice questions)
  • How to implement Comparator using lambda expression (see here)
  • 50+ SQL and Database Phone Interview questions (SQL questions)
  • 20+ JUnit Interview Questions for Java developers (questions)
  • 17 Spring AOP Interview Questions with Answers (list)
  • 25 Spring Security Interview Questions with Answers (questions)
  • How to use forEach() method in Java 8 (example)
  • How to use Stream API in Java 8 (learn here)
  • Understanding Default methods of Java 8 (learn here)
  • How to join String in Java 8 (example)
  • How to convert List to Map in Java 8 (solution)
  • 130+ Java Interview Questions with Answers (list)
  • How to use Stream class in Java 8 (tutorial)
  • 8 Best Lambda and Functional Programming courses (best courses)

Thanks for reading this article so far. If you like these example of flatMap function of Stream in Java then please share them with your friends and colleagues. If you have any questions or feedback about this Java 8 tutorial then please drop a note.

P.S.: If you are new to Java 8 and want to learn more about Lambda, Stream, and other new features in Java 8 in depth then you can also see these best Java 8 to Java 16 courses. It explains all important features of Java 8 like lambda expressions, streams, functional interface, Optional, new date, and time API, and other miscellaneous changes.    

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.