Tuesday, August 3, 2021

Java 8 Stream map() function Example with Explanation

The map is a well-known functional programming concept that is incorporated into Java 8. Map is a function defined in java.util.stream.Streams class, which is used to transform each element of the stream by applying a function to each element. Because of this property, you can use a map() in Java 8 to transform a Collection, List, Set, or Map. For example, if you have a list of String and you want to convert all of them into upper case, how will you do this? Prior to Java 8, there is no function to do this. You had to iterate through List using a for loop or foreach loop and transform each element. In Java 8, you get the stream, which allows you to apply many functional programming operators like the map, reduce, and filter.

By using the map() function, you can apply any function to every element of the Collection. It can be any predefined function or a user-defined function. You not only can use the lambda expression but also method references.

One example of Map in Java 8 is to convert a list of integers and then the square of each number. The map function is also an intermediate operation and it returns a stream of the transformed element.

Stream API also provides methods like mapToDouble(), mapToInt(), and mapToLong() which returns DoubleStream, IntStream and LongStream, which are specialized stream for double, int and long data types.

You can collect the result of transformation by using the Collectors class, which provides several methods to collect the result of transformation into List, Set, or any Collection.






What is Map Function in Java? How it works?

As I said, the Map function in Java 8 stream API is used to transform each element of Collection be it, List, Set, or Map. If you look at the declaration of map function from Stream class in Java then you will better understand it. 

Here is how the map function declaration looks like:

<R> Stream<R>  map​(Function<? super T,​? extends R> mapper)
This looks complex, isn't it? Well, it can be intimidating if you are not familiar with Generics and Functional programming but let's break it down. The map() function except for a parameter of type Function<? super T,​? extends R> which is a Function that takes a parameter of type T and returns a result of type R. 

For example, it can be Integer.parseInt(String number), which takes a string and returns an Integer. That's why you can pass any function whether it's a proper method or a shortcut code using lambda expression which can convert one type to other. The important detail to remember is that the argument type is T and the return type is R. 

And, if you look at the return type of map() function then its <R> Stream<R>, which is a stream of R, the same type which the function you passed to the map() method returns. The R is also the type of Stream on which you call the map function. 

In this Java 8 tutorial, we have used the map function for two examples, first to convert each element of List to upper case, and second to square each integer in the List.

By the way, this is just the tip of the iceberg of what you can do with Java 8. It's packed with many useful features and API enhancements like methods to join Strings, a new Date and Time API, Default methods, and much.

For a complete Functional Programming learning in Java, I suggest you check out Learn Java Functional Programming with Lambdas & Streams course by Ranga Karnam on Udemyone of the courses I have used to learn Java 8. It's a great online course to learn functional programming concepts like map, flatmap, filter, reduce, etc in Java.


How to use map function in Java 8



How to use the map() function in Java 8 and 11? Example

Now let's see an example to convert each element of a List to upper case using the map function. Once again, the map applies a mapping function on each element of Stream and stores result in another Stream.

package test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;

/**
 * Java 8 example to convert each element of List into upper case. You can use
 * Map function of Java 8 to transform each element of List or any collection.
 * @author Javin
 */
public class Java8MapExample {

    public static void main(String args[]) {
       List<String> cities = Arrays.asList("London", "HongKong", 
                                          "Paris", "NewYork");
       System.out.println("Original list : " + cities);
       System.out.println("list transformed using Java 8 :" 
                                   + transform(cities));
       System.out.println("list transformed using loop before Java 8 : " 
                                   + beforeJava8(cities));
       
       
       // You can even on the fly tranform Collection in Java using
       // Map function
       // let's transform a List of integers to square each element
       List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
       List<Integer> squares = numbers.stream()
                                      .map( i -> i*i)
                                      .collect(Collectors.toList());
       System.out.println("original list of numbers : " + numbers);
       System.out.println("transformed list of integers using Map in Java 8 : "
                                   + squares);

    }

    /**
     * This is how you convert all elements of list into upper case 
     * using loop before Java 8
     * @param listOfString
     * @return List with each element converted into upper case
     */
    public static List<String> beforeJava8(List<String> listOfString) {
        List<String> coll = new ArrayList<>();
        for (String str : listOfString) {
            coll.add(str.toUpperCase());
        }
        return coll;
    }

    /**
     * You can use Java 8 map function to transform each element of list
     * @param listOfString
     * @return list of elements with upper case
     */
    public static List<String> transform(List<String> listOfString) {
        return listOfString.stream() // Convert list to Stream
                .map(String::toUpperCase) // Convert each element to upper case
                .collect(toList()); // Collect results into a new list
    }

}

Output
run:
Original list : [London, HongKong, Paris, NewYork]
list transformed using Java 8 :
[LONDON, HONGKONG, PARIS, NEWYORK]
list transformed using loop before Java 8 :
 [LONDON, HONGKONG, PARIS, NEWYORK]
original list of numbers : [1, 2, 3, 4, 5, 6, 7, 8, 9]
transformed list of integers using Map in Java 8 : 
[1, 4, 9, 16, 25, 36, 49, 64, 81]
BUILD SUCCESSFUL (total time: 0 seconds)


How Map Function works in Java? Explanation of code

In this program, we have learned how to transform a List using the map function in Java 8 and how it was done before Java 8 without using lambdas and method reference. In the first example, we have a list of String that contains the name of the famous cities in a small letter.

We then converted that list into another list where names are in capital letters. This is achieved by applying the map() function to each element. The map method was passed the toUppercase() method to convert a small letter value to a capital letter value.

In the next example, we had a list of numbers from 1 to 9 and we transformed it into another list where numbers are square of each number. This is achieved by again applying a map function with calculating the square of each number passed to it.

You can see that you can pass the map function any code or function to do the transformation you need. It's a very powerful functional programming concept and every Java developer should learn it as you will use it quite often in your day-to-day task.  

Even though Java is moving really fast and we are already in Java 11, still a lot of developers have to learn Java 8, particularly the functional programming aspect.

 If you think that your Java 8 skills are not at par or you want to improve yourself, I suggest you join a comprehensive Java course like given in this list of best core Java courses. It covers everything you need to know and was also recently updated for Java 11.

That's all about how you transform each element of List in Java 8 using the Map function. It's tremendously useful and once you start using it, you will never look back. I found Java 8 really interesting, you will love to try it out. I really like a combination of lambda expression and Streams and solving problems without loops.



If you like this article and are hungry for more Java 8 tutorials, check these tutorials
  • 10 ways to use Lambda expression in Java 8 (read here)
  • Free Java 8 tutorials and Books (read the book)
  • Top 10 tutorials to Learn Java 8 (read more)
  • How to use Lambda Expression in Place of Anonymous class (read the tutorial)
  • How to use the Default method in Java 8. (see example)
  • Java 8 Comparator Example (see here)
  • How to convert List to Map in Java 8 (solution)
  • How to join String in Java 8 (example)
  • Difference between abstract class and interface in Java 8? (answer)
  • 10 Free Courses for Experienced Java Programmers (courses)
  • How to use peek() method in Java 8 (example)
  • How to sort the may by values in Java 8? (example)
  • How to format/parse the date with LocalDateTime in Java 8? (tutorial)
  • 5 Free Courses to learn Java 8 and 9 (courses)

Thanks for reading this article so far. If you like this tutorial then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.

P.S.: If you want to learn more about new features in Java 8 then please see the free Java 8 tutorial and courses. It explains all the important features of Java 8 e.g. lambda expressions, streams, functional interface, Optional, new Date Time API, and other miscellaneous changes.

7 comments:

  1. Nice article with good example

    ReplyDelete
  2. It's very detail post. Thanks for you helpful!

    ReplyDelete
  3. This is great article to start but there is a issue in transform method .collect(toList()) its ask to implement toList() method, we need to write .collect(Collectors.toList());

    ReplyDelete
    Replies
    1. As static import allows you to write .collect(toList())

      import static java.util.stream.Collectors.toList;

      Delete
  4. I found this method in a spring example and I have no idea what's going on. So thanks to help us.

    ReplyDelete
  5. I believe this syntax: Stream map(Function mapper) is incorrect. It needs to be Stream map(Function mapper)

    ReplyDelete

Feel free to comment, ask questions if you have any doubt.