The Java 8 Stream interface contains the map() and flatMap() methods that process the elements of the current Stream and return a new Stream. Both methods are intermediate stream operations and serve distinct purposes.
In this article, we’ll explore the differences between these operations and discuss when to use one over the other.
1. Stream map(): One-to-One Operation
The map() operation is used to transform each element of a stream into another object using a given function. It returns a new stream containing the transformed elements in the same order as the original stream.
This transformation is one-to-one, meaning each input element produces exactly one output element. So, if there are
N elements in the stream, the map() operation will produce a new stream of N elements.
List<String> listOfStrings = Arrays.asList("1", "2", "3", "4", "5"); List<Integer> listOfIntegers = listOfStrings.stream() .map(Integer::valueOf) .toList(); System.out.println(listOfIntegers); //[1, 2, 3, 4, 5]
2. Stream flatMap(): One-to-Many Operation
The flatMap() operation is used when each element in the stream is transformed into multiple elements, often in the form of another collection or stream. The resulting elements are then flattened into a single stream.
This transformation is one-to-many, meaning an input element produces multiple output elements, later all flattened into a single Stream.
In more simple words, the flatMap() operation is a two-step process i.e. map() + flattening. In a broader sense, it helps convert Collection<Collection<Item>> to Collection<Item>.
List<List<Integer>> listOfLists = Arrays.asList( Arrays.asList(1, 2, 3), Arrays.asList(4, 5), Arrays.asList(6, 7, 8) ); List<Integer> flattenedList = listOfLists.stream() .flatMap(list -> list.stream()) .toList(); System.out.println(flattenedList); //[1, 2, 3, 4, 5, 6, 7, 8]
3. Differences between Stream map() and flatMap()
The main difference between map() and flatMap() is that map() only transforms the elements of this Stream, but flatMap() transforms and flattens, both.
flatMap() = map() + Flattening
Let’s compare these two operations using a table:
|Transformation||One-to-one transformation||One-to-many transformation|
|Input to Output||1 input -> 1 output||1 input -> n outputs (flattened)|
|Output Sequence||Preserves input sequence||Flattens output|
|When to Use||Modify values, Extract properties||Splitting string, Combining nested collections|
|Common Usage||Normal data transformations||Handling nested structures|
4. Usage of map() vs flatMap()
Use Stream.map() when we need to transform each element individually and the output has a one-to-one relationship with the input.
For example, we can write a program to find the date of birth of all employees in a stream of employees. For each employee in the Stream, we will have one date of birth as the output value extracted from the input Employee object.
List<Employee> employees = ...; List<LocalDate> datesOfBirth = employees.stream() .map(Employee::getDateOfBirth) .collect(Collectors.toList());
Use flatMap() when we need to transform each element into multiple elements, such as when dealing with nested collections.
For example, we may write a program to find all district words from all lines in a text file. The following example:
- Reads a text file using
Files.lines()to obtain a stream of lines.
- The flatMap() operation transforms each line into a new Stream of words. This is the one-to-many transformation.
- The words from all the streams are collected into a single Set and it is the flattening operation.
String filePath = "path/to/your/textfile.txt"; Stream<String> lines = Files.lines(Paths.get(filePath)); Set<String> distinctWords = lines .flatMap(line -> Arrays.stream(line.split("\\s+"))) .collect(Collectors.toSet()); System.out.println("Distinct words in the file: " + distinctWords);
As discussed above, map() and flatMap(), both operations serve distinct purposes and are instrumental in streamlining data processing tasks. To keep things simpler, always remember that the
map() operation is designed for one-to-one transformations, and conversely, the
flatMap() operation handles one-to-many transformations.
Happy Learning !!