Java Stream map()

Java 8 Stream.map() operation transforms the elements of a stream from one type to another. After the map() operation completes, for each element of type X in the current Stream, a new object of type Y is created and put in the new Stream.

Stream<ElementType> —> map() operation —> Stream<NewElementType>

1. When do we use Stream.map() Operation?

The map() operation is particularly useful for data manipulation and transformation tasks. Consider a few possible usecases to understand when map() can be applied:

  • During database migration, we may want to transform data from the old schema to the new schema. Using map(), we can define the field mappings between entities to copy their values.
  • Data cleansing can be done with map() when we read data from different sources and convert it to a standard format before processing it in a standard way.
  • In the MVC pattern, we can use map() to copy JPA entity data into VO objects for rendering the user views.

In the following example, we are using the map() to convert from Stream<PersonEntity> to Stream<PersonVO>

// Converting from Stream<PersonEntity> to Stream<PersonVO> and collecting into a new List

List<PersonEntity> personEntityList = ...;  // A List of PersonEntity objects

List<PersonVO> personVoList = personEntityList.stream()
	.map(e -> createVoFromEntity(e))
	.toList();   

//The utility function called in the map operation
public static PersonVO createVoFromEntity(PersonEntity entity) { ... }

2. Stream map() Method

2.1. Method Syntax

The Stream map() method has the following syntax.

<R> Stream<R> map(Function<? super T,? extends R> mapper)
  • R represents the element type of the new stream.
  • mapper is a non-interfering, stateless function to apply to each element which produces a stream of new values.
  • The method returns a new stream of objects of type R.

2.2. Description

  • The map() is an intermediate operation. It returns a new Stream as return value.
  • The map() operation takes a Function, which is called for each value in the input stream and produces one result value sent to the output stream.
  • The mapper function used for transformation is a stateless function (does not store the information of previously processed objects) and returns only a single value.
  • The map() method is used when we want to convert a Stream of X to Stream of Y.
  • The mapped stream is closed after its contents have been placed into the new output stream.
  • map() operation does not flatten the stream as flatMap() operation does.

3. Stream map() Examples

Let us see a few more examples to understand it even better.

Example 1: Converting a Stream of Strings to a Stream of Integers

In this example, we will convert a Stream<String> to Stream<Integer>. Here the mapper function Integer::valueOf() takes one string from the Stream at a time, and converts the String to an Integer.

It then puts the Integer into another stream which is then collected using Collectors.toList().

List<String> listOfStrings = Arrays.asList("1", "2", "3", "4", "5");
 
List<Integer> listOfIntegers = listOfStrings.stream()
        .map(Integer::valueOf)
        .collect(Collectors.toList());
 
System.out.println(listOfIntegers);

Program output.

[1, 2, 3, 4, 5]

Example 2: Finding all distinct salaries among all employees

Java example to find all possible distinct salaries for a List of employees.

List<Employee> employeesList = Arrays.asList(
                                    new Employee(1, "Alex", 100),
                                    new Employee(2, "Brian", 100),
                                    new Employee(3, "Charles", 200),
                                    new Employee(4, "David", 200),
                                    new Employee(5, "Edward", 300),
                                    new Employee(6, "Frank", 300)
                                );
  
List<Double> distinctSalaries = employeesList.stream()
                        .map( e -> e.getSalary() )
                        .distinct()
                        .collect(Collectors.toList());

System.out.println(distinctSalaries);

Program output.

[100.0, 200.0, 300.0]

4. Stream of Integers, Longs or Doubles [Special Case]

Stream interface has three more similar methods for numeric types and are often used to perform numerical calculations or conversions. These methods produce IntStream, LongStream and DoubleStream respectively.

IntStream mapToInt(ToIntFunction<? super T> mapper)
LongStream mapToLong(ToLongFunction<? super T> mapper)
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper)

The benefit of using these classes is that they provide convenient methods to process the stream elements and perform mathematical/aggregate operations without the overhead of boxing and unboxing.

In the following example, we have a list of exam scores represented as strings, and we want to calculate the average score:

List<String> scoresAsString = Arrays.asList("85", "92", "78", "90", "88");

double averageScore = scoresAsString.stream()
  .mapToInt(Integer::parseInt)	// Convert strings to integers using mapToInt()
  .average()		// Calculate the average of the integers
  .orElse(0.0);	// Use 0.0 if there are no scores

System.out.println("Average score: " + averageScore);

Drop me your questions related to Stream map() method in Java Stream API.

Happy Learning !!

Sourcecode on Github

Comments

Subscribe
Notify of
guest
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode