The Java Stream API provides several aggregate operations to process data in a functional way. Two of these operations, map() and reduce(), are often used in combination to perform complex transformations on collections of data. While they are similar in some ways, they are also different and serve different purposes, so it’s important to understand both to know when to use each one.
Java map():
The map() operation is used to transform each element of a stream into a different element. This operation takes a function as an argument and applies it to each element of the stream, producing a new stream of the same size. The new stream consists of the result of applying the function to each element of the original stream. For example, if we have a stream of numbers, we can use the map() operation to square each number and get a new stream of squared numbers.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapReduce {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> squares = numbers.stream().map(n -> n * n).collect(Collectors.toList());
System.out.println(squares);
}
}
Output:
[1, 4, 9, 16, 25]
In the above example, the map() operation takes the lambda expression n -> n * n
as an argument. This lambda expression takes an integer n
and returns its square. The result of applying this function to each element of the stream is a new stream of integers, each of which is the square of the corresponding element in the original stream.
Java reduce():
The reduce() operation, on the other hand, is used to aggregate the elements of a stream into a single value. This operation takes two arguments: an initial value and a binary operator that is applied to each element of the stream and the previous result. The binary operator takes two arguments and returns a new value, which becomes the new result. The process is repeated until all elements of the stream have been processed, and the final result is returned.
import java.util.Arrays;
import java.util.List;
public class MapReduce {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(sum);
}
}
Output:
15
In this example, the reduce() operation takes the initial value 0
and the lambda expression (a, b) -> a + b
as arguments. This lambda expression takes two integers a
and b
and returns the sum of a
and b
. The result of applying this function to each element of the stream is a new value, which is the sum of all elements of the stream.
map() vs reduce() Differences:
The main difference between map() and reduce() is the purpose they serve. The map() operation is used to transform each element of a stream into a different element, whereas the reduce() operation is used to aggregate the elements of a stream into a single value. The result of the map() operation is a new stream, whereas the result of the reduce() operation is a single value.
Another difference is the type of function each operation takes as an argument. The map() operation takes a function that takes a single element of the stream as an argument and returns a new element, whereas the reduce() operation takes a binary operator that takes two elements of the stream and returns a new value.
map() and reduce() where should we use:
The map()
method is used to transform elements in a stream. It takes a Function as an argument, and applies the function to each element in the stream, producing a new stream with the transformed elements. The map()
method is useful for converting elements from one type to another, for example, converting a stream of strings to a stream of integers.
The reduce()
method, on the other hand, is used to aggregate elements in a stream. It takes two arguments: an initial value and a BinaryOperator, and aggregates elements in the stream using the binary operator. The reduce()
method is used to compute a single value from a stream, such as finding the sum, minimum, or maximum value.
In terms of use cases, the map()
method is useful when you need to transform elements in a stream, while the reduce()
method is useful when you need to aggregate elements in a stream. For example, you might use the map()
method to convert a stream of strings to a stream of integers, and then use the reduce()
method to find the sum of the integers in the stream.
In terms of performance, the map()
method is typically faster than the reduce()
method because it does not need to aggregate elements in the stream. However, the performance of both operations can be affected by the number of elements in the stream, the size of the data being processed, and the complexity of the functions being applied.
map() | reduce() |
---|---|
The map() method is used to apply a function to each element of a stream and return a new stream with the results. | The reduce() method is used to reduce a stream to a single value by combining the elements of the stream in a specified manner. |
The map() method returns a new stream and does not modify the original stream. | The reduce() method modifies the original stream and returns a single value. |
The map() method can be used to transform elements in a stream, such as converting them to a different type, or performing mathematical operations on them. | The reduce() method can be used to aggregate elements in a stream, such as computing a sum, or finding the minimum or maximum value. |
The map() method can be used in conjunction with other aggregate operations, such as filter(), sorted(), and collect(). | The reduce() method can be used in conjunction with other aggregate operations, such as filter(), sorted(), and collect(), but is typically used at the end of a chain of operations to produce the final result. |
References:
Happy Learning 🙂