JB Header
Java 8 Mapping with Streams | map and flatMap methods tutorial with examples
Introduction Java 8 Mapping with Streams tutorial explains the concept of mapping with streams using the map & flatMap methods with examples to show their usage. It assumes that you are familiar with basics of Java 8 Streams APITutorial on Basics of Java 8 Streams API. What is mapping with Streams Mapping in the context of Java 8 Streams refers to converting or transforming a Stream carrying one type of data to another type.

Lets take an example. Say we have a stream containing elements of type String. Suppose what we need is a stream of data which contains Integer values with each Integer value of the new stream being the length of corresponding String in the old stream. I.e we need to convert Stream<String> to its corresponding Stream<Integer>.

Such conversion from one type to another is possible with the map() method of streams. On top of the map() method, streams provide a flatmap() method which helps in flattening and converting multi-level streams into a single stream. Lets see both of these methods in detail now. Definition & usage of map() method The map() method helps us transform one type of stream to another type of stream.
Definition of map() method in java.util.stream.Stream<T> is -
<R> Stream<R> map(Function<? super T,? extends R> mapper)
Where,
Usage of map() method shown with an example
Java 8 code showing Stream.map() method usage
public class Employee{
 private String name;
 private Integer age;
 public Employee(String name, Integer age){
  this.name=name;
  this.age=age;
 }
 //Standard setters, getters, equals & hashcode
}
import static java.util.stream.Collectors.toList;
import java.util.Arrays;
import java.util.List;
public class StreamsMapping {
 static List<Employee> employeeList =
     Arrays.asList(new Employee("Tom Jones", 45), 
       new Employee("Harry Major", 25),
       new Employee("Ethan Hardy", 65),
       new Employee("Nancy Smith", 15),
       new Employee("Deborah Sprightly", 29));
 public static void main(String args[]) {
  List<String> mappedList = employeeList.stream().
                     map(emp -> emp.getName()).
                     collect(toList());
  mappedList.forEach(System.out::println);
 }
}
 OUTPUT of the main() method
Tom Jones
Harry Major
Ethan Hardy
Nancy Smith
Deborah Sprightly
Salient points of above map() method example
  • StreamsMapping class run's the example in its main() method & contains a static list of Employee type of objects.
  • map() method is used to convert the Stream of Employees to a Stream of Strings with just the employee names.
  • Conversion from Employee type to String type is achieved using a Function instance defined by the lambda expressionRead Lambda Expressions Tutorial - emp -> emp.getName()
  • The output obtained on printing the mappedList contents are all the employee names.
Definition & usage of flatMap() method The flatMap() method gives us the ability to flatten a multi-level stream obtained as a result of mapping each element of the input stream to a stream, and then creating a single stream out of this stream of streams.
Definition of flatMap() method in java.util.stream.Stream<T> is -
<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
Where,
  • flatMap() method takes as input an instance of Function<T,R>, named mapper, which converts the type of elements in the stream from the current type T to another stream of type R
  • It returns as output a stream of type R which is actually a flattened stream containing the elements in all the streams of type R obtained when mapper is applied on the input stream's elements of type T.
  • For n elements in input stream of type T we first get n streams of type R. Then these n streams are flattened into a single stream of type R. So, a Stream<Stream<R>> becomes Stream<R>.
Usage of flatMap() method with an example Note - the StreamsMapping class used in the previous example is same, as also the Employee list defined in it. For brevity, I have included just the main() method here -
Java 8 code showing Stream.flatMap() method usage
 public static void main(String args[]) {
  List<String> nameCharList = employeeList.stream()
  	       .map(emp-> emp.getName().split(""))
	       .flatMap(array->Arrays.stream(array))
	       .map(str -> str.toUpperCase()) 
	       .filter(str -> !(str.equals(" ")))
	       .collect(toList());
   nameCharList.forEach(str -> System.out.print(str));
  }
}
 Output of the main() method is
TOMJONESHARRYMAJORETHANHARDYNANCYSMITHDEBORAHSPRIGHTLY
Salient points of above flatMap() method example
  • The objective of the above code is to get all the alphabets used in the names of all the employees in caps for making their embossed name-plates.
  • map(emp-> emp.getName().split("")) converts the stream of Employees to a stream of Employee names' array. I.e. converts from Stream<Employee> to Stream<String[]>.
  • flatMap() method converts Stream<String[]> into first a Stream<Stream<String>> and then flattens it to Stream<String> i.e. a stream of single character Strings.
  • map() is applied next, which converts this Stream<String>’s contents to uppercase and then filters out the space characters using the filter() method.
  • We have the required list at the end which contains all the alphabets in caps for all the employees, which is the output obtained on printing the namecharlist.
Note - there are other variants of map() & flatMap() methods which work with DoubleStreams, LongStreams & IntStreams. These are more specific forms of the general map() & flatMap() I have explained above. These have not been covered in this tutorial. Summary This tutorial explained what is meant by Mapping in Streams followed by definition & usage of map() & flatMap() methods with examples.