Java Stream API
The Java Stream API is a powerful tool for processing data in Java. It allows you to declaratively specify how data should be processed, making it easier to read, write, and understand.
- A Stream represents a sequence of elements supporting sequential and parallel aggregate operations.
collapsed:: true
- Sequential
logseq.order-list-type:: number
id:: 66e00de8-0740-4720-82e4-ac655e3953f5
- processing happens in a single thread, so each element is handled in sequence.
- Parallel
logseq.order-list-type:: number
- elements are processed concurrently using multiple threads. The stream is divided into chunks, and each chunk is processed simultaneously in different threads.
- Here, the numbers may be processed in any order, as they are handled by different threads simultaneously.
- Sequential
logseq.order-list-type:: number
id:: 66e00de8-0740-4720-82e4-ac655e3953f5
- Streams don’t store data, they operate on the source (like a collection).
- Streams are lazily evaluated (operations are performed only when required).
-
creating streams
- can be created from collections, arrays, or by generating data.
collapsed:: true
- collections
logseq.order-list-type:: number
- arrays
logseq.order-list-type:: number
Stream.of()
logseq.order-list-type:: number- Infinite streams
logseq.order-list-type:: number
- collections
logseq.order-list-type:: number
- can be created from collections, arrays, or by generating data.
collapsed:: true
-
stream operations
collapsed:: true- Intermediate operations
logseq.order-list-type:: number
collapsed:: true
- return a new stream
- lazy (executed only when a terminal operation is called)
- Examples
- ((66e04318-15f8-4319-ac29-1b059b24296f))
- ((66e043a1-8ef5-4ec7-829d-e16926a9fc2f))
- ((66e04327-51b8-4e2b-a431-4f3098b3f888))
- ((66e04415-d131-424b-be0b-ceb015f76225))
- ((66e0441b-49b0-4830-8874-da5498cf3063))
- ((66e0442a-679d-42ff-8ef6-8ca8deba0a0b))
- Terminal operations
logseq.order-list-type:: number
collapsed:: true
- triggers the execution of stream operations & produces a result
- Examples
- collect
- forEach
- reduce
- count
- findFirst
- findAny
- allMatch
- anyMatch
- noneMatch()
-
id:: 66e04318-15f8-4319-ac29-1b059b24296ffilter
- Filters elements based on a predicate.
-
id:: 66e043a1-8ef5-4ec7-829d-e16926a9fc2fmap
- Transforms elements
-
id:: 66e03e87-f326-4c66-9796-ef23826b8b62 collapsed:: trueflatMap
- flatMap() flattens nested structures (e.g., streams of lists).
- flatMap() takes a function that returns a stream for each element. It then concatenates these streams into a single stream.
- Examples:
-
- the function
List::stream
converts each list into a stream, andflatMap()
combines all these streams into one. - $$[ [John, Jane], [Mike, Kelly] ] -> Stream[John, Jane, Mike, Kelly] $$
- the function
-
- $$[Hello, world, Java, Stream, API, flatMap, example]$$
-
-
id:: 66e04327-51b8-4e2b-a431-4f3098b3f888 collapsed:: truedistinct
- Removes duplicate elements from the stream based on the equals() method.
-
id:: 66e04415-d131-424b-be0b-ceb015f76225sorted
-
id:: 66e0441b-49b0-4830-8874-da5498cf3063limit
-
id:: 66e0442a-679d-42ff-8ef6-8ca8deba0a0bskip
-
reduce
- Example: sum of numbers
- Example: concatenate strings
- Example: sum of numbers
peek
- Allows you to perform a side-effect operation (such as logging) on each element as it passes through the stream.
- mainly for debugging.
-
collect
- Collects the result of the stream into a collection (like a List, Set, or Map) or even performs more advanced operations like summarizing.
- Example (collecting to a List):
- Example (grouping by length):
forEach()
reduce()
- Reduces the stream to a single value.
count()
- Returns the number of elements in the stream.
findFirst()
,findAny()
- Find the first or any element.
allMatch()
,anyMatch()
,noneMatch()
collapsed:: true- short-circuiting operations that check if all, any, or none of the elements in the stream match a given predicate.
toArray
- Intermediate operations
logseq.order-list-type:: number
collapsed:: true
-
#Interview Topics
- Difference between
map()
andflatMap()
id:: 66e0158f-f2b5-4243-930f-27d6c8f92949 collapsed:: true- map() transforms each element in the stream into another form (e.g., applying a function to each element).
- flatMap() flattens nested structures into a single-level stream and then not only transforms each element into another form
- Lazy evaluation ?
collapsed:: true
- Intermediate operations (like map() and filter()) don’t execute until a terminal operation (like collect()) is called.
- Stream vs. Collection?
collapsed:: true
- Streams don’t store data, whereas collections store data. Streams are consumed once, collections can be reused.
- How does the
filter()
method work internally, and when is it best used? collapsed:: true- The filter() method takes a predicate and processes each element in the stream. If the predicate evaluates to true for an element, that element is included in the resulting stream.
- Internally, filter() is a lazy intermediate operation, meaning it doesn’t perform the operation until a terminal operation is invoked.
- It’s best used when you want to filter out elements based on a specific condition, like retaining only even numbers from a list or filtering out null values.
- How does
reduce()
work, and what are some common use cases? collapsed:: true- reduce() performs a reduction on the elements of the stream, using an [[associative]] accumulation function and optionally an identity value.
- without an identity, it returns an Optional
- allows you to produce a single result from the stream, such as
- summing numbers,
- concatenating strings,
- or finding the minimum or maximum element.
- Example (Sum of numbers):
- Example (Finding maximum value):
- reduce() performs a reduction on the elements of the stream, using an [[associative]] accumulation function and optionally an identity value.
- What is the difference between Collection.stream() and Collection.parallelStream()?
- Collection.stream(): Creates a sequential stream, meaning elements are processed one by one in a single thread.
- Collection.parallelStream(): Creates a parallel stream that splits the data into multiple chunks and processes them in parallel using the [[ForkJoinPool]] , with the goal of improving performance on large datasets.
- Parallel streams can improve performance in certain scenarios, but not all; they introduce overhead for managing concurrency and are best suited for [[CPU-bound tasks]].
- Calculate the sum of employees’ salaries and find the max salaries per department #RealInterview
- logseq.order-list-type:: number .mapToDouble(Employee::getSalary)
- logseq.order-list-type:: number
Collectors.toMap
-
- keyMapper: Function to extract or generate the key.
- valueMapper: Function to extract or generate the value.
- mergeFunction: Function that specifies what to do when duplicate keys are encountered.
-
- Difference between