Introduction

The map() and flatmap() are two very significant operations in Java. They both are methods of java.util.stream.Stream interface in Java 8 that is primarily used for transformation or mapping operations.

The Java flatmap() and map() methods were first just used in functional languages but they were soon introduced in Java 8.

The map() offers transformation whereas the flatmap() can be used for both transformations and flattening, thus the name flatmap.

In this article, we will further explore the map() and flatmap() methods, the key differences between them and will discover the correct and most suitable use of both of them with the aid of relevant examples.

new java job roles

Java Map()

The Java map() method takes one input value and produced one output hence, it is also referred to as One-To-One mapping.

 

The Syntax of the map() method is as follows:

<R> Stream<R> map(Function<? super T, ? extends R> mapper)
  • Here, the R is the element type of the new output stream.
  • The stream is an interface.
  • The T represents the type of stream elements.
  • The mapper is a stateless function that is applied to each element.
  • The function returns the new stream R.

The given mapper function is applied to each element of input Stream<T> and results are then stored in an output Stream<R>.

The map() function can be used where it is required to map the elements of a particular collection to a certain function, and the new stream containing the updated results is to be returned.

For instance, the map() can be used to Multiply all the elements of the list by 5 and then return the results in the updated list.

Java Map() Examples

List transformation

See the following code demonstration using the map() to transform a list:

1.     import java.io.*;
2. import java.util.*;
3. import java.util.ArrayList;
4. import java.util.List;
5. import java.util.stream.Collectors;
6. class MapMethodExample01 {
7.       public static void main(String[] args)
8.      {
9.          // the array list object is creatd
10.         ArrayList<String> country = new ArrayList<>();
11.         country.add("Poland");
12.         country.add("Pakistan");
13.         country.add("Australia");
14.         country.add("Uganda");
15.         country.add("China");
16.         country.add("USA");
17.         country.add("Turkey");
18.         System.out.println("List of Countries : " + country);
19.  
20.         // Now map() is used to transform the list of countries
21.         List list = country.stream()
22.                     .map(s -> s.length())
23.                     .collect(Collectors.toList());
24.         System.out.println("Transformed list : " + list);
25.     }
26. }

 

 Following is the output:

List of Countries : [Poland, Pakistan, Australia, Uganda, China, USA, Turkey]

Transformed list : [6, 8, 9, 6, 5, 3, 6]

First, an array list object is created where names of some countries are added to the array list. The Map() method is then used to transform the list into the length of the name of each country added to the array list.

In the code demonstrated above, Stream<Country> is an input stream for map().  s -> s.length() is the mapper function that is applied to each Country and the result is collected in a List called list.

Data Extraction:

See this another example where Map() is used to extract data from a list. Suppose we have a country List where each Country consists of two fields.

 

One is the name of the country and another one is its some notable cities wrapped in another List as shown below:

1. import java.util.List;
2. import java.util.stream.Collectors;
3. class MapMethodExample02 {
4.       public static void main(String[] args)
5.       {
6. List<Country> countryList = new ArrayList<>();
7. countryList.add(new Country("USA", Arrays.asList("New York", "Chicago", "Washington D.C.", "Miami")));
8. countryList.add(new Country("Pakistan", Arrays.asList("Karachi", "Islamabad", "Lahore", “Multan” )));
9. countryList.add(new Country("India", Arrays.asList("Delhi", "Mumbai", "Lucknow", "Bangalore")));

 

Now, you can extract name of each Country, using the map() method as shown below:

1. List<String> namesOfCountries = countryList.stream()
2.                                .map(Country::getName)
3. 
4.    .collect(Collectors.toList());
5. System.out.println("The Transformed list : " + namesOfCountries);
6.       }
7. }
8. }

In the above code snippet, Stream<Country> is an input stream for map().

Country::getName is the mapper function that is applied to each Country and the outcome is collected in a List<String> called namesOfCountries.

 

The output will be:

The Transformed list : [USA, Pakistan, India]

Now, if you attempt to extract the cities of all countries, using map() It will throw an error. It is because cities are wrapped in another List<String> forming a list within a list.

This will require the use of the Java flatMap() method to get the correct result. Now, we will be exploring flatMap() in detail.

Java flatmap

The flatMap() method is used where it is required to flatten out or transform a string, as the flattening process cannot be done using the map().

 

The Syntax of the flatMap() is as follows:

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)

The map() method is limited to mapping, but flatMap() performs mapping as well as flattening. Flattening is the process of transforming data from the Stream<Stream<T>> to Stream<T>. This is the key difference between map() and flatMap().

The Java flatMap() function takes the Stream<Stream<T> as input and output the transformed Stream of type R. Unlike the map() function, the mapper function in the Java flatmap() method produces not one but multiple values for each value of input stream and those multiple values are then flattened into a result Stream<R>.

For instance, Getting the first character of all the strings in a List of Strings and returning the result in form of a stream.

As explained in the previous example, the Java flatMap() method is needed to extract the cities from the list of counties.

 

In the code demonstrated below, the previous example is extended to get unique cities of all Countries using the Java flatmap() method:

List<String> citiesOfcountries = countryList.stream().flatMap(Country -> 
Country.getCities().stream()).collect(Collectors.toList());
System.out.println("The Transformed list : " + citiesOfCountries);
    }

In these lines of code, Country -> Country.getCities() is a mapper function which is producing multiple values for every input. It means there are multiple cities for each single Country. flatMap() is flattening these multiple values into a single stream.

Here we are simply collecting the stream into a list but as per your requirements, the stream can also be collected into various other types such as into Set.

 

The output will be:

The Transformed list : [New York, Chicago, Washington D.C., Miami, Karachi,
 Islamabad, Lahore, Multan, Delhi, Mumbai, Lucknow ]

Java flatmap vs map

The key difference between the Java flatmap() and map() function is that when we use a map() method, it applies the mapper function on each element of the stream and stores the value returned by the function into a new Stream.

Hence, one stream is transformed into another stream like in the very first example where a Stream of String is transformed into a Stream of Integer where each element is the length of the corresponding Stream.

A noteworthy thing is that the mapper function used for transformation using the map() function always returns a single value. If we want that every single value returns a Stream of values like in the last examples, then we have a Stream of stream of values, and Java flatmap() is then required to first flatten that into a Stream of values.

For example, if we have a Stream of Integer containing two values, {4, 12}, and a method getMultiples() is used as a mapper function that returns a list of 5 multiples of the given integer.

When you will use this function with the map(), you will this as output, [[4, 8, 12, 16, 20, 24],[12, 24, 36, 48, 60]].

 

If the same function is used with flatmap, you will get a flattened Stream of Integers like this:

[4, 8, 12, 16, 20, 24, 12, 24, 36, 48, 60].

 

Following is summarized version of Java flatmap vs map:

Map() FlatMap()
Map() is only used for transformation. FlatMap() is used for both transformation and mapping.
Map() returns a stream of value. It returns a stream of stream value.
The mapper function passed to map() returns a single value for a single input. The function passed to flatmap() operation returns multiple numbers of values as the output.
One-to-one mapping. One-to-many mapping.

Conclusion

That was all about the difference between Java flatmap() and Map(). In this article, we have discussed some key differences between Java flatmap and map function with some examples to understand their workings.

You must use a map() method if you just want to transform a single stream into another where each element will be converted to one single value.

Also Read: Guide to hashCode() in Java

FlatMap() must be used if the mapper function will return multiple values and you want them to be in one list. Now, you must be able to choose the most suitable method based on the requirements of your program.

new Java jobs

Author

Shaharyar Lalani is a developer with a strong interest in business analysis, project management, and UX design. He writes and teaches extensively on themes current in the world of web and app development, especially in Java technology.

Write A Comment