Stream API in Java
Introduction
The Stream API in Java, introduced in Java 8, provides a powerful and flexible way to perform operations on collections of objects. It allows for functional-style operations on streams of elements, making it easier to process data in a declarative way.
What is a Stream?
A Stream in Java represents a sequence of elements supporting sequential and parallel aggregate operations. Streams are not data structures; they do not store elements. Instead, they convey elements from a source such as a collection, array, or I/O channel through a pipeline of computational operations.
Basic Operations on Stream
Streams support a variety of operations, which are categorized into:
- Intermediate operations: These operations return a new stream and are lazy, meaning they are not executed until a terminal operation is invoked. Examples include
filter()
,map()
, andsorted()
. - Terminal operations: These operations trigger the processing of the stream and produce a result or side effect. Examples include
collect()
,forEach()
, andreduce()
.
Example 1: Creating a Stream from a Collection
You can create a stream from a collection, such as a List
or Set
, using the stream()
method.
import java.util.List; import java.util.Arrays; public class StreamExample { public static void main(String[] args) { Listnumbers = Arrays.asList(1, 2, 3, 4, 5); // Create a stream from the list and print each element numbers.stream().forEach(System.out::println); } }
In this example, the stream()
method creates a stream from the numbers
list, and the forEach()
terminal operation prints each element.
Example 2: Filtering Data using Stream API
You can use the filter()
method to filter elements from the stream based on a given condition. This is an example of an intermediate operation.
import java.util.List; import java.util.Arrays; public class StreamExample { public static void main(String[] args) { Listnumbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); // Filter even numbers and print them numbers.stream() .filter(num -> num % 2 == 0) .forEach(System.out::println); } }
In this example, filter()
filters out the odd numbers from the stream, leaving only the even numbers. The result is then printed.
Example 3: Mapping Data using Stream API
You can use the map()
method to transform the elements in a stream. The map()
method applies a given function to each element and returns a new stream with the transformed elements.
import java.util.List; import java.util.Arrays; public class StreamExample { public static void main(String[] args) { Listnumbers = Arrays.asList(1, 2, 3, 4, 5); // Square each number and print the results numbers.stream() .map(num -> num * num) .forEach(System.out::println); } }
In this example, the map()
method squares each number in the stream, and the result is printed.
Example 4: Sorting Data using Stream API
You can use the sorted()
method to sort elements in the stream. The default sorting order is ascending.
import java.util.List; import java.util.Arrays; public class StreamExample { public static void main(String[] args) { Listnumbers = Arrays.asList(5, 2, 8, 1, 3); // Sort the numbers in ascending order and print numbers.stream() .sorted() .forEach(System.out::println); } }
In this example, the sorted()
method sorts the numbers in ascending order, and the result is printed.
Example 5: Reducing Data using Stream API
The reduce()
method is a terminal operation that allows you to reduce the elements of a stream to a single result. It takes a binary operator that combines two elements of the stream.
import java.util.List; import java.util.Arrays; public class StreamExample { public static void main(String[] args) { Listnumbers = Arrays.asList(1, 2, 3, 4, 5); // Sum all numbers using reduce int sum = numbers.stream() .reduce(0, (a, b) -> a + b); System.out.println("Sum: " + sum); } }
In this example, the reduce()
method sums all the numbers in the stream, starting with an initial value of 0
.
Parallel Streams
Java Streams can be processed in parallel to take advantage of multi-core processors. You can create a parallel stream by calling parallelStream()
instead of stream()
on a collection.
import java.util.List; import java.util.Arrays; public class StreamExample { public static void main(String[] args) { Listnumbers = Arrays.asList(1, 2, 3, 4, 5); // Create a parallel stream and print each element numbers.parallelStream().forEach(System.out::println); } }
In this example, parallelStream()
creates a parallel stream, which processes the elements in parallel.
Conclusion
The Stream API is a powerful addition to Java, enabling a more functional and concise way to process data. By using streams, you can easily perform operations like filtering, mapping, sorting, and reducing in a declarative style.