Java Streams: Where Simplicity Meets Power: Thinking Differently
Java Streams: Where Simplicity Meets Power: Thinking Differently
With just a few lines of code, Java Streams can replace complex loops, unlock
parallelism, and turn data processing into elegant expressions. It’s not just
about shorter code — it’s about thinking differently.
Get ready to write logic that’s clean, fast, and functional. From chaining
operations to embracing immutability and lazy evaluation, Streams reward
those who master their flow — and punish those who don’t.
Main Interfaces:
Stream<T>
IntStream, LongStream, DoubleStream
1. Creation of Streams
Method Description Example
stream() Converts a collection into a sequential list.stream()
stream
condition
map(Function) Transform elements stream.map(String::toUpperCase)
equals())
sorted() Sorts elements (natural order) stream.sorted()
Note: Intermediate operations are lazy — no processing happens until a terminal operation
is called.
3. Terminal Operations (triggers stream processing)
Method Description Example
collect(Collector) Collects elements into a stream.collect(Collectors.toList())
collection
forEach(Consumer) Performs an action for each stream.forEach(System.out::println)
element
toArray() Converts stream into array stream.toArray()
single result
count() Counts number of elements stream.count()
comparator
max(Comparator) Largest element based on stream.max(Comparator.naturalOrder())
comparator
anyMatch(Predicate) True if any element stream.anyMatch(x -> x > 10)
matches
allMatch(Predicate) True if all elements match stream.allMatch(x -> x > 0)
(Optional)
findAny() Returns any element (useful stream.findAny()
in parallel)
4. Collectors (for collect())
Collectors.toList() → Collects into a List
Collectors.toSet() → Collects into a Set
Collectors.toMap(keyMapper, valueMapper) → Collects into a Map
Collectors.groupingBy(Function) → Groups elements by a key
Collectors.partitioningBy(Predicate) → Partitions elements into two groups
(true/false)
List<String> names = List.of("Alice", "Bob", "Charlie");
Map<Integer, List<String>> groupedByLength = names.stream()
.collect(Collectors.groupingBy(String::length));
Methods like sum(), average(), min(), max() are available directly on primitive streams.
F Difference Between stream() and parallelStream()
Feature stream() parallelStream()
Processing Sequential: one element at a Parallel: splits data into multiple chunks and
time, in one thread (usually main processes them simultaneously using multiple
thread). threads (ForkJoinPool).
Speed Good for small or simple Can be faster for large datasets if system has
datasets. multiple cores.
Performance Simple and low overhead. Adds overhead due to splitting and combining —
benefits only when heavy work is done.
Ideal Use Case Small datasets, operations where Large datasets, CPU-intensive operations, when
order matters, I/O operations. order doesn't matter much.
Q2: From a list, find all pairs that sum to a given number (e.g., 10).
List<Integer> nums = List.of(1, 2, 3, 7, 5, 8, 6, 4);
int target = 10;
Q3: Find the first string that starts with letter "C".
List<String> names = List.of("Alice", "Bob", "Charlie", "David");
firstNameStartingWithC.ifPresent(System.out::println); // Output:
Charlie
Q4: Find the sum of squares of numbers in a list.
List<Integer> numbers = List.of(1, 2, 3, 4);
Sol
int sumOfSquares = numbers.stream()
.map(n -> n * n)
.reduce(0, Integer::sum);
System.out.println(groupedByLength);
// Output: {3=[one, two], 5=[three], 4=[four, five]}
System.out.println(count); // Output: 3
Q12: Given a list of sentences, count the frequency of each word (case-insensitive).
List<String> sentences = List.of("Java is fun", "Streams are
powerful", "Java is powerful");
Q13: From a list of integers, find the duplicate numbers and how many times they occur.
// Output: [1, 2, 3, 4, 5, 6]
Q15:
Return the common elements between two lists using streams.
Q19: Given a list of lowercase strings, return the list of characters that appear in every string.
// Output: [e, l, l]