UNIT 5 CLASS NOTES
UNIT 5 CLASS NOTES
.map(String::toUpperCase)
.collect(Collectors.toList());
• Filtering Data: Streams make it easy to filter data based on certain criteria.
For instance, filtering out even numbers from a list:
.filter(n -> n % 2 != 0)
.collect(Collectors.toList());
.mapToInt(Integer::intValue)
.sum();
• Parallel Processing: Streams can be processed in parallel to improve
performance. For example, summing a large list of integers in parallel:
.mapToInt(Integer::intValue)
.sum();
• Complex Data Pipelines: Streams can be used to create complex data processing
pipelines. For example, filtering, mapping, and collecting data in a single pipeline:
.map(String::toLowerCase)
.collect(Collectors.toList());
Java's stream API
• Simplified Data Processing
Importance: Advanced stream features simplify complex data processing tasks, making the code more readable and
maintainable by abstracting away the boilerplate code.
Use Cases:
Data Transformation: Converting a list of objects into another form, such as mapping user entities to DTOs (Data
Transfer Objects).
Filtering Data: Easily filtering large datasets based on specific criteria, such as finding all active users or filtering
transactions above a certain threshold.
• Parallel Processing
Importance: Streams can be processed in parallel to leverage multi-core processors, which improves performance
when dealing with large data sets.
Use Cases:
Batch Processing: Handling large batches of data, such as processing millions of records in a database.
Big Data: Performing complex computations over large datasets, like summing up values or aggregating
statistics.
• Functional Programming Integration
Importance: Streams provide a functional programming approach to data processing,
which allows for more expressive and concise code.
Use Cases: Event Handling: Using streams in event-driven systems to handle and
process events functionally.
Custom Collectors: Creating custom collectors for complex data aggregations, such as
grouping and partitioning data.
• Enhanced Debugging and Testing
Importance: Advanced stream features, such as peek and custom collectors, help in
debugging and testing stream operations by providing intermediate operation insights.
Use Cases: Logging: Using peek() to log stream elements as they are processed, which
aids in debugging complex streams.
Testable Pipelines: Breaking down stream operations into smaller, testable units,
making it easier to verify the correctness of each stage.
• Stream Customization and Extension
Importance: Java allows customization and extension of stream
behavior through custom collectors, spliterators, and more, which
increases the flexibility of the stream API.
• Use Cases:
Custom Collectors: Implementing custom collectors for specific
aggregation needs, such as collecting statistics with custom rules.
Spliterators: Creating custom spliterators for non-standard data
sources, like iterating over data structures that aren't inherently
sequential.
Creating Custom Streams
Creating custom streams in Java involves defining a stream from
non-standard data sources or operations that are not directly
supported by the standard Stream API.
• Spliterator
• Stream.Builder
• Stream.generate methods.
Steps to Create Custom Streams in Java
Stream<String> builtStream =
2. Using Stream.generate()
Stream<Double>randomNumbers=Stream.generate(Math::random).li
mit(10);
3. Using Stream.iterate()
}
INFINITE STREAMS