How to use flatMap() in Java 8 - Stream Example Tutorial

In order to understand the flatMap() method, you first need to understand the map() function of Java 8. The map() function is declared in  the java.util.stream.Stream class and uses to transform one Stream into another e.g. a stream of integer numbers into another stream of ints where each element is the square of the corresponding element in source stream. In the map() function, a function is applied to each element of Stream and return values are inserted into a new Stream. The key point to note here is that the function used by map() operation returns a single value. Now, if the map operation uses a function which instead of returning a single value returns a Stream of values e.g. prime factors of the number then you have a Stream of Stream of integers. The flatMap() method is used to flatten that stream into a Stream of integers. For example, suppose, you have a list of numbers e.g. [21, 23, 42] and we use getPrimeFactors() method along with the map() operation to transform this stream. The result would be [[3,7],[23],[2,3,7]]. If you want to flat this stream of a stream into a stream of values, you can use the flatMap() which will return [3,7,2,3,2,3,7].


In short, a flatMap() is used to convert a Stream of Stream into a list of values, for more details you can also read Java SE 8 for Really Impatient, one of the best book to learn new features of Java 8 e.g. lambda expression, streams, new Date and Time API and other enhancements.

How to use flatMap() method in Java 8 with example




Java  8 FlatMap Example

Here is a sample Java program to demonstrate how to use the flatMap() function in Java 8. As I told, you can use the flatMap() to flatten a Stream of Stream of values into just a Stream of values. In our example, we have a Stream of the list of String and by using the flatMap() we convert this into just a Stream of String to get the full list of players participating in cricket world cup 2016. This operation is really useful to get the full list by combining several small lists.


It's said that a picture is worth a thousand words and this is true, following image explains how flatMap works in Java 8 quite easily:

Java 8 flatMap example with streams


and here is our Java program to demonstrate how to use the Stream.flatMap() in Java 8.

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() function in Java 8.
 * The flatMap() function is used to convert a Stream of list of values to
 * just a Stream of values. This is also called flattening of stream.
 *
 * @author Javin Paul
 */
public class Test {

    public static void main(String args[]) {

        List<String> teamIndia = Arrays.asList("Virat", "Dhoni", "Jadeja");
        List<String> teamAustralia = Arrays.asList("Warner", "Watson", "Smith");
        List<String> teamEngland = Arrays.asList("Alex", "Bell", "Broad");
        List<String> teamNewZeland = Arrays.asList("Kane", "Nathan", "Vettori");
        List<String> teamSouthAfrica = Arrays.asList("AB", "Amla", "Faf");
        List<String> teamWestIndies = Arrays.asList("Sammy", "Gayle", "Narine");
        List<String> teamSriLanka = Arrays.asList("Mahela", "Sanga", "Dilshan");
        List<String> teamPakistan = Arrays.asList("Misbah", "Afridi", "Shehzad");
        
        List<List<String>> playersInWorldCup2016 = new ArrayList<>();
        playersInWorldCup2016.add(teamIndia);
        playersInWorldCup2016.add(teamAustralia);
        playersInWorldCup2016.add(teamEngland);
        playersInWorldCup2016.add(teamNewZeland);
        playersInWorldCup2016.add(teamSouthAfrica);
        playersInWorldCup2016.add(teamWestIndies);
        playersInWorldCup2016.add(teamSriLanka);
        playersInWorldCup2016.add(teamPakistan);
        
        // Let's print all players before Java 8
        List<String> listOfAllPlayers = new ArrayList<>();
        
        for(List<String> team : playersInWorldCup2016){
            for(String name : team){
                listOfAllPlayers.add(name);
            }
        }
        
        System.out.println("Players playing in world cup 2016");
        System.out.println(listOfAllPlayers);
        
        
        // Now let's do this in Java 8 using FlatMap
        List<String> flatMapList = playersInWorldCup2016.stream()
                                                        .flatMap(pList -> pList.stream())
                                                        .collect(Collectors.toList());
        
        System.out.println("List of all Players using Java 8");
        System.out.println(flatMapList);
    }

}

Output
run:
Players playing in world cup 2016
[Virat, Dhoni, Jadeja, Warner, Watson, Smith, Alex, Bell, Broad, Kane, Nathan, Vettori, AB, Amla, Faf, Sammy, Gayle, Narine, Mahela, Sanga, Dilshan, Misbah, Afridi, Shehzad]
List of all Players using Java 8
[Virat, Dhoni, Jadeja, Warner, Watson, Smith, Alex, Bell, Broad, Kane, Nathan, Vettori, AB, Amla, Faf, Sammy, Gayle, Narine, Mahela, Sanga, Dilshan, Misbah, Afridi, Shehzad]
BUILD SUCCESSFUL (total time: 0 seconds)

You can see that final list contains all the elements from each list. So flatMap() is working fine to flatten a Stream of List of String into just a Stream of String, that's the true power of flat map operation in Java 8.


That's all about how to use the flatMap() function in Java 8.  Just remember the difference between map() and flatMap() in Java 8 and when to use the map() vs flatMap(). If you use a function which returns a list of values in map() operation you get a Stream of Stream and by using flatMap you can convert that to Stream of values. In short, you can combine several small list of values into a big list of values using flatMap(). It's called flatMap() because it flattens the Stream. Read Java SE 8 for Really Impatient to learn more.


No comments:

Post a Comment