Java provides facilities to programmers to perform functional-style operations on streams of elements. Programmers can define "Stream" as a sequence of ordered data that supports many different methods, but programmers cannot use them to store objects.
They can integrate them to produce the desired result. This article precisely explains how to work with the map() method in stream operations and fetch a stream of desired results.
What are streams in Java?
Streams are an abstraction of a non-mutable collection of functions operated in an ordered data set. Programmers can create a stream from different data structures, such as lists, sets, etc. But it is not a data structure itself. Streams can be collections but also: Arrays, I/O channels, primitive data types, etc.
The "java.util.stream" is an additional package provided by Java in Java 8. The package includes different classes, interfaces, and enum; that allow programmers to implement functional-style operations on the data objects. Programmers can use stream after they import the "java.util.stream" package.
Following are some features of Java stream:
- As mentioned earlier, a Java stream is simply functional in nature and an abstraction of a non-mutable collection of functions. It is not a data structure. But it takes input or conveys elements from a source such as a data structure, Arrays, or I/O channels using a pipeline of computational operations.
- Stream is inert and operates code only when programmers direct as per the pipelined methods.
- Java streams can never modify the original data structure. These only return the output as per the pipelined computational operations.
- The stream allows users to visit the objects in it once during the life of the stream. Programmers can generate a new stream like an iterator for revisiting the same collection of elements of the stream.
- Programmers can perform various intermediate operations with pipelined computational methods. Terminal operations signify the end of the Java stream by returning the result.
Types of Java Stream
The Java stream can be sequential, which programmers can create using stream(), or parallel, which they can create using parallelStream(). Parallel streams can work on multiple threads, while sequential streams cannot.
Following are some methods that perform operations on stream in Java:
Intermediate Operation
map(), filter(), and sorted() are the operations listed in this category. These operations return a stream. Programmers can chain multiple intermediate operations without using semicolons.
- map() method: Programmers can use the map() method to return a stream containing all the results of applying the given method to each element of the original stream.
- filter() method: Programmers can use the filter() method to select elements according to the Predicate passed as an argument.
- sorted() method: Programmers can use this method to sort the stream.
Terminal operations
collect(), foreach(), and reduce() are the operations listed in this category. These operations are either void or return a non-stream output.
Programmers specify the operations as "terminal" because they cannot chain multiple operations once they have used one terminal. They create a new stream from the original operation and start again.
- collect() method: Programmers can use this method to return the output of the intermediate operations performed on the original stream.
- orEach() method: Programmers can use this method to iterate through each element of the Java stream.
- reduce() method: Programmers can use this method to reduce the elements of the original stream and convert it into a single value. They can pass BinaryOperator as the parameter into the method.
Examples of the Stream.map()
Let us first see the syntax and understand it in-depth.
Syntax :
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
- Here, R indicates the element type of the new stream.
- Stream specifies an interface, and T represents the type of stream elements. The mapper argument is a stateless function that the method applies to each element. The function returns the new stream.
Example 1: Multiplication Operation
Code Snippet:
import java.util.*;
class Demo {
// Here, we write the driver code
public static void main(String[] args)
{
System.out.println("The method will generate a new stream after using "
+ "the function : ");
// Here, we create a list of integers
List<Integer> l = Arrays.asList(2, 4, 6, 8, 10);
l.stream().map(num -> num * 5).forEach(System.out::println);
}
}
Output:
Explanation:
Here, we have created a list of integers and called stream() on the list to return a new stream of elements. We have mapped each integer value using the map() method and multiplied them by 5. Lastly, using the map() method, we returned the stream.
We used the forEach() method to print each element in the stream.
Example 2: Stream of Strings to Stream of Integers
Now let us see how the map() method converts a stream of strings into a stream of integers.
Code Snippet:
import java.util.*;
import java.util.stream.Collectors;
class Demo {
// Here, we write the driver code
public static void main(String[] args)
{
System.out.println("The method will generate a new stream of integers using "
+ "the function : ");
// Here, we create a list of Strings
List<String> l = Arrays.asList("1", "2", "3", "4", "5", "6", "7");
List<Integer> mapped_List = l.stream()
.map(n -> Integer.parseInt(n))
.collect(Collectors.toList());
System.out.println(mapped_List);
}
}
Output:
Explanation:
Similarly, in the above example, we passed an array of strings containing "Number." Then, the map() function returned a new stream of integers after converting them from the stream of Java strings.
Lastly, we used the parseInt() method that converts the string input into an integer. The Integer class in the "java.lang" package includes this method.
Example 3: Stream of Integers to Stream of Strings
Code Snippet:
import java.util.*;
import java.util.stream.Collectors;
class Demo {
// Here, we write the driver code
public static void main(String[] args)
{
System.out.println("The method will generate a new stream of strings using " + "the function : ");
// Here, we create a list of Integers
List<Integer> l = Arrays.asList(1, 2, 3, 4, 5);
List<String> mapped_List = l.stream()
.map(n -> "Number " + String.valueOf(n))
.collect(Collectors.toList());
System.out.println(l);
System.out.println(mapped_List);
}
}
Output:
Explanation:
In the above example, we have created a list of integers and called stream() on the list to return a new stream of string elements. We have mapped each integer value using the map() method. Lastly, using the map() method, we returned the stream.
We used the collect() function to collect the elements back into the Collection object, such as a List, Map, Set, etc. (here, a list of string values). Lastly, we used the valueOf() method returning a relevant Number Object containing the value of the argument passed.
Example 4: Lowercase to Uppercase operation
Code Snippet:
import java.util.*;
import java.util.stream.Collectors;
class GFG {
public static void main(String[] args)
{
System.out.println("The stream after converting from lowercase to uppercase is: ");
// Creating a list of Integers
List<String> l = Arrays.asList("this", "is", "an", "example", "of", "java", "stream");
List<String> res = l.stream().map(String::toUpperCase).
collect(Collectors.toList());
System.out.println(res);
}
}
Output:
Explanation:
The Stream map() method converts all the lowercase characters to uppercase and prints them using the System.out.println() method.
Example 5: Mapping String Length in place of String
Code Snippet:
import java.util.*;
class Demo {
public static void main(String[] args)
{
System.out.println("The stream of length specifying each string are : ");
List<String> l = Arrays.asList("this", "is", "an", "example", "of", "java", "stream");
l.stream().map(string -> string.length()).forEach(System.out::println);
}
}
Output:
Explanation:
The Stream map() method maps all the string lengths in place of the string and prints them using System.out.println() method.
Conclusion:
The article has mentioned five scenarios of how the map() method works in the stream to perform different basic operations. All these have respective examples and explanations clarifying how and when to use the function in the Java program. But the binding fact is that streams are not obligatory in programming.
Nevertheless, programmers can use these to improve the readability of their code significantly. These are expensive and becoming a standard programming practice.