Usage of flatMap() in Java Streams

The flatMap() method in Java Streams is used to flatten nested structures, such as List<List<T>>, into a single stream of elements.

map() vs flatMap()

Featuremap()flatMap()
OutputStream of Streams (Stream<Stream<T>>)Single Flattened Stream (Stream<T>)
Use CaseTransformation without flatteningTransformation with flattening
Example InputList<List<String>>List<List<String>>
Example OutputStream<List<String>>Stream<String>

Example 1: Using map() vs flatMap()

Using map() (Without Flattening)

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

public class MapExample {
    public static void main(String[] args) {
        List<List<String>> listOfLists = Arrays.asList(
            Arrays.asList("Apple", "Banana"),
            Arrays.asList("Orange", "Grape")
        );

        // Using map() (Returns Stream<List<String>>)
        List<Stream<String>> mappedResult = listOfLists.stream()
            .map(List::stream)
            .collect(Collectors.toList());

        System.out.println(mappedResult);
    }
}

Output:

[Stream@1a2b3c4d, Stream@5e6f7g8h]

Problem: It returns Stream<List<String>>, which is not useful for direct processing.

Using flatMap() (Flattening the Stream)

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

public class FlatMapExample {
    public static void main(String[] args) {
        List<List<String>> listOfLists = Arrays.asList(
            Arrays.asList("Apple", "Banana"),
            Arrays.asList("Orange", "Grape")
        );

        // Using flatMap() (Returns Stream<String>)
        List<String> flatMappedResult = listOfLists.stream()
            .flatMap(List::stream)
            .collect(Collectors.toList());

        System.out.println(flatMappedResult);
    }
}

Output:

[Apple, Banana, Orange, Grape]

Solution: flatMap() merges multiple lists into one single list.

Example 2: Extracting Words from Sentences

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

public class FlatMapWordsExample {
    public static void main(String[] args) {
        List sentences = Arrays.asList(
            "Java is powerful", 
            "Streams are useful"
        );

        // Using flatMap to split and flatten words
        List words = sentences.stream()
            .flatMap(sentence -> Arrays.stream(sentence.split(" ")))
            .collect(Collectors.toList());

        System.out.println(words);
    }
}

Output:

[Java, is, powerful, Streams, are, useful]

Benefit: Converts sentences into individual words.

Example 3: Flattening Integer Lists

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

public class FlatMapIntegerExample {
    public static void main(String[] args) {
        List<List<Integer>> listOfNumbers = Arrays.asList(
            Arrays.asList(1, 2, 3),
            Arrays.asList(4, 5, 6)
        );

        // Flattening lists of integers
        List<Integer> flatNumbers = listOfNumbers.stream()
            .flatMap(List::stream)
            .collect(Collectors.toList());

        System.out.println(flatNumbers);
    }
}

Output:

[1, 2, 3, 4, 5, 6]

Purpose: Combines multiple integer lists into one.

Generating a Visual Flowchart for Better Understanding

I will now generate an image illustration of how flatMap() works. Stay tuned! 🎨

Here is a flowchart-style pictorial representation of how the flatMap() method works in Java Streams. Let me know if you need any modifications!

Here are the More Examples for the flapMap()

package java8;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
 class Dept {
	private String name;
	private List<String> deptList;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<String> getDeptList() {
		return deptList;
	}
	public void setDeptList(List<String> deptList) {
		this.deptList = deptList;
	}
	 Dept(String name,List<String> depList){
		this.name = name;
		this.deptList = depList;
	}
}
public class FlatMapExample {
    public static void main(String[] args) {
        List<String> sentences = Arrays.asList(
            "Java is fun",
            "Streams are powerful",
            "FlatMap is useful"
        );

        // Using flatMap() to extract words
        List<String> words = sentences.stream()
            .flatMap(sentence -> Arrays.stream(sentence.split(" ")))
            .filter(word -> word.startsWith("F"))
            .collect(Collectors.toList());
        System.out.println(words);
        
        //Using flatmap() to count the letters
       Map<String,Long> opList = sentences.stream()
    		   .flatMap(sentence -> Arrays.stream(sentence.split(""))
    				   .filter(a->!a.isBlank())
    				   .map(a->a.toLowerCase()))
    		   .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
       System.out.println(opList);
       
      //Using flatMap() in a Java Object
       List<Dept> dpList = Arrays.asList(new Dept("Shiva",Arrays.asList("IT","HR")),new Dept("Stephen",Arrays.asList("Network","Security")), new Dept("Ravi",Arrays.asList("Admin","Tech")));
       List<String> allDepartments = dpList.stream()
    		   .flatMap(d->d.getDeptList().stream())
    		   .collect(Collectors.toList());
       System.out.println(allDepartments);
       
      //Using flatMap() with Method Reference to Split the Sentence
      List<Character> opString = sentences.stream()
    		  .flatMapToInt(String::chars)
    		  .mapToObj(a->(char)a).distinct()
    		  .collect(Collectors.toList());
      System.out.println(opString);
      
    }
}

Output:

[FlatMap]
{a=6, e=4, f=4, i=2, j=1, l=3, m=2, n=1, o=1, p=2, r=3, s=5, t=2, u=4, v=1, w=1}
[IT, HR, Network, Security, Admin, Tech]
[j, a, v,  , i, s, f, u, n, t, r, e, m, p, o, w, l]

Why Use flatMap()?

  • Converts multiple streams into a single stream.
  • Handles nested collections efficiently.
  • Useful for transforming and flattening data in functional programming.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *