
Mastering Java Streams API: A Beginner’s Guide with Practical Examples
May 27, 2025 3 Min Read 346 Views
(Last Updated)
Ever feel bogged down with endless loops and wordy code as you go about handling data in Java? Worry no more, as the Java Streams API comes in the least expected way-with simplicity and power combined. Its functional programming approach makes you look at processing data in a whole new way. We’ll dig into the magic of Java Streams with practical examples: making your code not just efficient but elegant. This is a guide for beginners. Yes! Code smarter, not harder. We’re all set to master the flow! Let’s get started!
Table of contents
- What is a Stream?
- Creating Streams
- Stream Operations
- Common Stream Methods with Examples
- Parallel Streams
- Real-World Example: Using Streams to Process Data
- Conclusion
What is a Stream?
A Stream in Java, as part of the Java Streams API, represents a sequence of elements supporting various operations to process these elements. It’s important to note that streams do not store data—they only provide a view on the underlying data source (like arrays, collections, or I/O channels).
1. Creating Streams
You can create a stream in various ways:
- Using Stream.of()
- From Collections using stream() or parallelStream()
- Using Arrays.stream()
import java.util.*; import java.util.stream.*; public class Main{ public static void main(String[] args) { // Creating a Stream from a Collection List<String> names = Arrays.asList(“John”, “Jane”, “Jack”, “Doe”); Stream<String> nameStream = names.stream(); // Creating a Stream from an Array String[] array = {“One”, “Two”, “Three”}; Stream<String> arrayStream = Arrays.stream(array); // Creating a Stream using Stream.of() Stream<Integer> numberStream = Stream.of(1, 2, 3, 4, 5); nameStream.forEach(System.out::println); } } |
2. Stream Operations
Stream operations are divided into intermediate and terminal operations:
- Intermediate Operations: Return a new stream (e.g., filter(), map(), sorted()).
- Terminal Operations: Produce a result or side effect (e.g., forEach(), collect(), count()).
3. Common Stream Methods with Examples
3.1 filter()
The filter() method filters elements based on a given predicate (condition).
java
Copy code
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> evenNumbers = numbers.stream()
.filter(num -> num % 2 == 0)
.collect(Collectors.toList());
System.out.println(“Even Numbers: ” + evenNumbers);
Output:
Even Numbers: [2, 4, 6]
3.2 map()
The map() method transforms each element in a stream into another form using a function.
List<String> names = Arrays.asList(“john”, “doe”, “mary”); List<String> capitalizedNames = names.stream() .map(String::toUpperCase) .collect(Collectors.toList()); System.out.println(“Capitalized Names: ” + capitalizedNames); Output: Capitalized Names: [JOHN, DOE, MARY] |
3.3 sorted()
The sorted() method sorts elements in natural order or using a custom comparator.
List<String> unsortedNames = Arrays.asList(“John”, “Jane”, “Alex”, “Chris”); List<String> sortedNames = unsortedNames.stream() .sorted() .collect(Collectors.toList()); System.out.println(“Sorted Names: ” + sortedNames); Output: Sorted Names: [Alex, Chris, Jane, John] |
3.4 distinct()
The distinct() method removes duplicate elements in a stream.
List<Integer> numbersWithDuplicates = Arrays.asList(1, 2, 2, 3, 4, 4, 5); List<Integer> distinctNumbers = numbersWithDuplicates.stream() .distinct() .collect(Collectors.toList()); System.out.println(“Distinct Numbers: ” + distinctNumbers); |
Output: Distinct Numbers: [1, 2, 3, 4, 5] |
3.5 limit() and skip()
- limit() restricts the number of elements in the stream.
- skip() skips the specified number of elements.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); List<Integer> limitedNumbers = numbers.stream().limit(5).collect(Collectors.toList()); List<Integer> skippedNumbers = numbers.stream().skip(5).collect(Collectors.toList()); System.out.println(“Limited Numbers: ” + limitedNumbers); // Output: [1, 2, 3, 4, 5] System.out.println(“Skipped Numbers: ” + skippedNumbers); // Output: [6, 7, 8, 9] |
3.6 collect()
The collect() method collects the elements of a stream into a collection, such as a List, Set, or Map.
List<String> names = Arrays.asList(“John”, “Jane”, “Jack”); Set<String> nameSet = names.stream().collect(Collectors.toSet()); System.out.println(“Set of Names: ” + nameSet); |
3.7 reduce()
The reduce() method performs a reduction on the elements of the stream using an associative accumulator function and returns an Optional value.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int sum = numbers.stream().reduce(0, (a, b) -> a + b); System.out.println(“Sum of Numbers: ” + sum); |
3.8 forEach()
The forEach() method iterates over each element in the stream and performs a given action.
Stream<String> nameStream = Stream.of(“Alice”, “Bob”, “Charlie”); nameStream.forEach(name -> System.out.println(“Hello, ” + name)); |
4. Parallel Streams
Streams can be converted to parallel streams for multi-threaded processing. It’s useful for large collections to take advantage of multi-core processors.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); int parallelSum = numbers.parallelStream().reduce(0, Integer::sum); System.out.println(“Sum using Parallel Stream: ” + parallelSum); |
5. Real-World Example: Using Streams to Process Data
Let’s see how to use multiple stream methods together for a more complex example:
class Product { String name; int price; Product(String name, int price) { this.name = name; this.price = price; } } List<Product> products = Arrays.asList( new Product(“Laptop”, 800), new Product(“Phone”, 600), new Product(“Tablet”, 400), new Product(“TV”, 900) ); List<String> affordableProducts = products.stream() .filter(p -> p.price < 700) // Select products below $700 .map(p -> p.name) // Get the names of these products .sorted() // Sort the names .collect(Collectors.toList()); System.out.println(“Affordable Products: ” + affordableProducts); |
Output: Affordable Products: [Phone, Tablet] |
Conclusion
Congratulations! Just unlocked the potential of Java Streams API, a toolbox that turns simple data operations into art. From filtering and mapping to reducing and collecting you are now equipped with skills to craft cleaner, more efficient Java code. And the most exciting part: streams are just the first piece of what Java will offer today! Experiment further, keep learning, and let the stream of possibilities flow. Boost your Java skills by practicing code directly in the GUVI IDE—hands-on learning made easy and effective!
Did you enjoy this article?