What is the Stream API in Java 8?
Stream API provides a functional approach to process collections of objects. Streams allow declarative processing with operations like filter, map, reduce, and collect.
Stream Basics
import java.util.*;
import java.util.stream.*;
public class StreamBasics {
public static void main(String[] args) {
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Traditional approach (imperative)
System.out.println("=== Traditional Approach ===");
List evenNumbersOld = new ArrayList<>();
for (int num : numbers) {
if (num % 2 == 0) {
evenNumbersOld.add(num);
}
}
System.out.println("Even numbers: " + evenNumbersOld);
// Stream approach (declarative)
System.out.println("
=== Stream Approach ===");
List evenNumbersStream = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("Even numbers: " + evenNumbersStream);
// Chain multiple operations
System.out.println("
=== Chained Operations ===");
int sumOfSquaresOfEvens = numbers.stream()
.filter(n -> n % 2 == 0) // Filter even numbers
.map(n -> n * n) // Square them
.reduce(0, Integer::sum); // Sum them
System.out.println("Sum of squares of evens: " + sumOfSquaresOfEvens);
// Understanding Stream pipeline
System.out.println("
=== Stream Pipeline Visualization ===");
numbers.stream()
.filter(n -> {
System.out.println("Filtering: " + n);
return n % 2 == 0;
})
.map(n -> {
System.out.println("Mapping: " + n);
return n * n;
})
.limit(3)
.forEach(n -> System.out.println("Result: " + n));
// Creating streams from different sources
System.out.println("
=== Creating Streams ===");
// From Collection
Stream fromList = numbers.stream();
// From array
Integer[] array = {1, 2, 3, 4, 5};
Stream fromArray = Arrays.stream(array);
// From values
Stream fromValues = Stream.of("a", "b", "c");
// Infinite streams
Stream iterate = Stream.iterate(0, n -> n + 2);
Stream generate = Stream.generate(Math::random);
// Stream from range
IntStream range = IntStream.range(1, 10);
IntStream rangeClosed = IntStream.rangeClosed(1, 10);
}
}
Intermediate Operations
public class IntermediateOperations {
public static void main(String[] args) {
List words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");
System.out.println("Original list: " + words);
// 1. filter - keep elements matching predicate
System.out.println("
=== filter (length > 5) ===");
words.stream()
.filter(w -> w.length() > 5)
.forEach(System.out::println);
// 2. map - transform each element
System.out.println("
=== map (to uppercase) ===");
words.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
// 3. flatMap - flatten nested streams
System.out.println("
=== flatMap (flatten lists) ===");
List> nestedList = Arrays.asList(
Arrays.asList(1, 2, 3),
Arrays.asList(4, 5, 6),
Arrays.asList(7, 8, 9)
);
List flatList = nestedList.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
System.out.println("Nested: " + nestedList);
System.out.println("Flat: " + flatList);
// 4. distinct - remove duplicates
System.out.println("
=== distinct ===");
List withDuplicates = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 5, 5, 6);
List distinct = withDuplicates.stream()
.distinct()
.collect(Collectors.toList());
System.out.println("With duplicates: " + withDuplicates);
System.out.println("Distinct: " + distinct);
// 5. sorted - sort elements
System.out.println("
=== sorted ===");
List unsorted = Arrays.asList(5, 2, 8, 1, 9, 3, 7, 4, 6);
List sorted = unsorted.stream()
.sorted()
.collect(Collectors.toList());
System.out.println("Unsorted: " + unsorted);
System.out.println("Sorted: " + sorted);
// Custom sorting
List sortedByLength = words.stream()
.sorted(Comparator.comparingInt(String::length))
.collect(Collectors.toList());
System.out.println("Sorted by length: " + sortedByLength);
// 6. limit - limit size
System.out.println("
=== limit (first 3) ===");
words.stream()
.limit(3)
.forEach(System.out::println);
// 7. skip - skip first n elements
System.out.println("
=== skip (skip first 2) ===");
words.stream()
.skip(2)
.forEach(System.out::println);
// 8. peek - debug/intermediate
System.out.println("
=== peek (debugging) ===");
long count = words.stream()
.peek(w -> System.out.println("Before: " + w))
.map(String::toUpperCase)
.peek(w -> System.out.println("After: " + w))
.count();
}
}
Terminal Operations
import java.util.Optional;
public class TerminalOperations {
public static void main(String[] args) {
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 1. collect - accumulate into collection
System.out.println("=== collect ===");
List collected = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("Even numbers: " + collected);
Set set = numbers.stream()
.filter(n -> n > 5)
.collect(Collectors.toSet());
System.out.println("Set of numbers > 5: " + set);
// 2. toArray - convert to array
System.out.println("
=== toArray ===");
Integer[] array = numbers.stream()
.filter(n -> n % 2 == 0)
.toArray(Integer[]::new);
System.out.println("Array: " + Arrays.toString(array));
// 3. forEach - iterate
System.out.println("
=== forEach ===");
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
// 4. reduce - combine elements
System.out.println("
=== reduce ===");
Optional sum = numbers.stream()
.reduce((a, b) -> a + b);
System.out.println("Sum: " + sum.orElse(0));
int product = numbers.stream()
.reduce(1, (a, b) -> a * b);
System.out.println("Product: " + product);
int max = numbers.stream()
.reduce(Integer.MIN_VALUE, Integer::max);
System.out.println("Max: " + max);
// 5. count - count elements
System.out.println("
=== count ===");
long count = numbers.stream()
.filter(n -> n % 2 == 0)
.count();
System.out.println("Even numbers count: " + count);
// 6. min/max - find min/max
System.out.println("
=== min/max ===");
Optional min = numbers.stream().min(Integer::compareTo);
Optional maxNum = numbers.stream().max(Integer::compareTo);
System.out.println("Min: " + min.orElse(0));
System.out.println("Max: " + maxNum.orElse(0));
// 7. anyMatch/allMatch/noneMatch
System.out.println("
=== match operations ===");
boolean anyEven = numbers.stream().anyMatch(n -> n % 2 == 0);
boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0);
boolean noneNegative = numbers.stream().noneMatch(n -> n < 0);
System.out.println("Any even number? " + anyEven);
System.out.println("All numbers even? " + allEven);
System.out.println("No negative numbers? " + noneNegative);
// 8. findFirst/findAny
System.out.println("
=== findFirst/findAny ===");
Optional first = numbers.stream()
.filter(n -> n % 2 == 0)
.findFirst();
System.out.println("First even: " + first.orElse(0));
Optional any = numbers.parallelStream()
.filter(n -> n % 2 == 0)
.findAny();
System.out.println("Any even (parallel): " + any.orElse(0));
}
}
Collectors Utility
public class CollectorsDemo {
static class Person {
String name;
int age;
String city;
double salary;
Person(String name, int age, String city, double salary) {
this.name = name;
this.age = age;
this.city = city;
this.salary = salary;
}
@Override
public String toString() {
return name + "(" + age + "," + city + ")";
}
}
public static void main(String[] args) {
List people = Arrays.asList(
new Person("Alice", 25, "NYC", 75000),
new Person("Bob", 30, "LA", 80000),
new Person("Charlie", 25, "NYC", 65000),
new Person("David", 35, "Chicago", 90000),
new Person("Eve", 28, "LA", 70000),
new Person("Frank", 25, "NYC", 60000)
);
// 1. groupingBy
System.out.println("=== groupingBy ===");
Map> byAge = people.stream()
.collect(Collectors.groupingBy(p -> p.age));
System.out.println("Group by age: " + byAge);
Map> byCity = people.stream()
.collect(Collectors.groupingBy(p -> p.city));
System.out.println("Group by city: " + byCity);
// 2. groupingBy with counting
System.out.println("
=== groupingBy with counting ===");
Map countByCity = people.stream()
.collect(Collectors.groupingBy(p -> p.city, Collectors.counting()));
System.out.println("Count by city: " + countByCity);
// 3. groupingBy with summing
System.out.println("
=== groupingBy with summing ===");
Map salaryByCity = people.stream()
.collect(Collectors.groupingBy(p -> p.city,
Collectors.summingDouble(p -> p.salary)));
System.out.println("Total salary by city: " + salaryByCity);
// 4. groupingBy with averaging
System.out.println("
=== groupingBy with averaging ===");
Map avgSalaryByCity = people.stream()
.collect(Collectors.groupingBy(p -> p.city,
Collectors.averagingDouble(p -> p.salary)));
System.out.println("Average salary by city: " + avgSalaryByCity);
// 5. partitioningBy
System.out.println("
=== partitioningBy ===");
Map> adults = people.stream()
.collect(Collectors.partitioningBy(p -> p.age >= 30));
System.out.println("Adults: " + adults.get(true));
System.out.println("Young adults: " + adults.get(false));
// 6. joining
System.out.println("
=== joining ===");
String names = people.stream()
.map(p -> p.name)
.collect(Collectors.joining(", "));
System.out.println("Names: " + names);
// 7. summarizingInt/Double
System.out.println("
=== summarizing ===");
IntSummaryStatistics stats = people.stream()
.collect(Collectors.summarizingInt(p -> p.age));
System.out.println("Age stats - Avg: " + stats.getAverage() +
", Max: " + stats.getMax() +
", Min: " + stats.getMin() +
", Sum: " + stats.getSum());
// 8. mapping while collecting
System.out.println("
=== mapping while collecting ===");
Map> namesByAge = people.stream()
.collect(Collectors.groupingBy(p -> p.age,
Collectors.mapping(p -> p.name, Collectors.toSet())));
System.out.println("Names by age: " + namesByAge);
// 9. toMap
System.out.println("
=== toMap ===");
Map nameSalaryMap = people.stream()
.collect(Collectors.toMap(p -> p.name, p -> p.salary));
System.out.println("Name to salary: " + nameSalaryMap);
}
}
Parallel Streams
public class ParallelStreams {
public static void main(String[] args) {
// Create large list
List numbers = IntStream.rangeClosed(1, 10000000)
.boxed()
.collect(Collectors.toList());
System.out.println("=== Performance Comparison ===
");
// Sequential stream
long start = System.currentTimeMillis();
long sequentialSum = numbers.stream()
.mapToLong(Long::valueOf)
.sum();
long sequentialTime = System.currentTimeMillis() - start;
// Parallel stream
start = System.currentTimeMillis();
long parallelSum = numbers.parallelStream()
.mapToLong(Long::valueOf)
.sum();
long parallelTime = System.currentTimeMillis() - start;
System.out.println("Sequential sum: " + sequentialSum + " Time: " + sequentialTime + "ms");
System.out.println("Parallel sum: " + parallelSum + " Time: " + parallelTime + "ms");
System.out.println("Parallel is " + (sequentialTime - parallelTime) + "ms faster");
System.out.println("Speedup: " + (double)sequentialTime / parallelTime + "x
");
// When to use parallel streams
System.out.println("=== When to Use Parallel Streams ===");
System.out.println("✓ Large data sets (thousands+ elements)");
System.out.println("✓ CPU-intensive operations");
System.out.println("✓ Stateless operations");
System.out.println("✓ Operations that can be executed independently");
System.out.println("
=== When NOT to Use Parallel Streams ===");
System.out.println("✗ Small data sets (overhead > benefit)");
System.out.println("✗ Order-sensitive operations (use forEachOrdered)");
System.out.println("✗ Operations with shared mutable state");
System.out.println("✗ I/O-bound operations");
// Example: Maintaining order with parallel streams
System.out.println("
=== Maintaining Order ===");
List orderedList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
System.out.println("forEach (order not guaranteed):");
orderedList.parallelStream()
.forEach(n -> System.out.print(n + " "));
System.out.println("
forEachOrdered (order maintained):");
orderedList.parallelStream()
.forEachOrdered(n -> System.out.print(n + " "));
System.out.println();
// Performance test with different operations
System.out.println("
=== Operation Type Impact ===");
// CPU-intensive operation
start = System.currentTimeMillis();
long sequentialCpu = numbers.stream()
.map(n -> {
for (int i = 0; i < 1000; i++) Math.sqrt(n);
return n;
})
.count();
long seqCpuTime = System.currentTimeMillis() - start;
start = System.currentTimeMillis();
long parallelCpu = numbers.parallelStream()
.map(n -> {
for (int i = 0; i < 1000; i++) Math.sqrt(n);
return n;
})
.count();
long parCpuTime = System.currentTimeMillis() - start;
System.out.println("CPU-intensive task:");
System.out.println(" Sequential: " + seqCpuTime + "ms");
System.out.println(" Parallel: " + parCpuTime + "ms");
System.out.println(" Parallel " + (double)seqCpuTime/parCpuTime + "x faster");
}
}
Master Java 8 Stream API with Online Learner!
0
likes
Your Feedback
Help us improve by sharing your thoughts
Online Learner helps developers master programming, database concepts, interview preparation, and real-world implementation through structured learning paths.
Quick Links
© 2023 - 2026 OnlineLearner.in | All Rights Reserved.
