0% found this document useful (0 votes)
93 views52 pages

Advanced Java Unit 3

Uploaded by

23102208
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
93 views52 pages

Advanced Java Unit 3

Uploaded by

23102208
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

III Unit

• Overview of Stream API –


• Importance of Stream API in Java 8 and Beyond
• Functional Programming Concepts
• Creating Streams - Stream Interface Methods
• StreamOperations- Intermediate Filtering (filter)-Mapping (map, flatMap)-
Sorting (sorted)
• Distinct (distinct)- Limit and Skip (limit, skip)
• Terminal Operations -Collecting Results(collect) - Reducing and Summarizing
(reduce, summaryStatistics)-Iterating (forEach)
• Matching and Finding (anyMatch, allMatch, noneMatch, findFirst, findAny) –
• Counting(count).
Overview of Stream API
❑A stream is a sequence of elements from a source that supports aggregate operations.
❑Unlike collections, streams do not store elements.
❑ Instead, they convey elements from a source (such as a collection, array, or I/O
channel) through a pipeline of computational operations.
❑ Different Operations On Streams Normal program
❑ There are two types of Operations in Streams:
❑ Intermediate Operations
❑ Terminate Operations

Stream.java
Functional Programming Concepts
• It is a declarative style of programming rather than imperative.
• The basic objective of this style of programming is to make code more concise,
less complex, more predictable, and easier to test compared to the legacy style of
coding.
• Lambda expressions: A Lambda expression is an anonymous method that has
mutability at very minimum and it has only a parameter list and a body.

•In its simple form, a lambda could be represented as a comma-separated list of


parameters, the –> symbol and the body.
How Stream API Works?
A Java Stream is composed of 3 main phases.
KEY CHARACTERISTICS OF STREAMS
❑ Functional in Nature:Streams support functional-style operations such as map, filter,
reduce, collect, and forEach.

❑ No Storage: Streams do not store data. They are a view of the data that is consumed
once and cannot be reused.

❑ Laziness: Streams are lazy in the sense that intermediate operations are not executed
until a terminal operation is invoked. This allows for optimization, such as short-circuiting.

❑ Parallel Processing: Streams can be processed in parallel without the need for explicit
multi-threading, making it easier to write parallel code.

❑ Pipelining: Streams allow pipelining,where intermediate operations return another


stream, allowing multiple operations to be chained together to form a pipeline.
4. Reusability
Collections: Collections can be iterated multiple times.
Streams: Streams can be consumed only once. Once a stream is processed, it cannot be reused.
Parallelism
Collections: Parallel processing requires explicit handling using multi-threading.
Stream: Streams provide built-in support for parallel processing with methods like parallelStream.
❖ Conciseness: The stream version is more concise and expressive, using a functional
approach.
❖ Laziness: The stream version does not perform any operations until the terminal operation
collect is called.
❖ Pipelining: The stream version uses method chaining to form a pipeline of operations.

Inference:
❖ Streams in Java provide a powerful way to perform data processing operations in a
functional style.
❖ They differ from traditional data structures in their approach to storage, execution, and
parallelism.
❖ Streams do not store data, support lazy evaluation, and offer built-in parallel processing,
making them a versatile tool for modern Java development.
Difference Between Streams and Other Data Structures
Storage
Collections: Collections such as lists, sets, and arrays are data structures that store elements.
Streams : Streams do not store elements. They are used to process elements from a source

Nature of Operations
Collections: Operations on collections are typically performed explicitly using loops and
conditionals.
Streams :Operations on streams are performed using functional-style methods, which are
often more concise and readable.
3. Laziness:
Collections: Operations on collections are eager, meaning they are executed immediately
Streams:: Streams support lazy evaluation, where intermediate operations are not executed until a terminal
operation is invoked.
Generating Streams in Java:
With Java 8, Collection interface has two methods to generate a
Stream.

stream() − Returns a sequential stream considering collection


as its source.

parallelStream() − Returns a parallel Stream considering


collection as its source.

Ways to create stream


▪ parallelStream
Java Parallel Streams is a feature of Java 8 and higher, meant for
utilizing multiple cores of the processor.
Normally any java code has one stream of processing, where it is
executed sequentially.
Whereas by using parallel streams, we can divide the code into
multiple streams that are executed in parallel on separate cores
the final result is the combination of the individual outcomes. The
order of execution, however, is not under our control.
Stream Interface Methods:
stream.Filter():
The filter() method is used to filter a stream. Let’s use the above stream example to filter out the
languages list based on specific criteria, i.e., items starting with ‘E.’
stream.filter(item->item.startsWith(“E”));
• The filter() method takes a predicate as a parameter. The predicate interface contains a function
called boolean test(T t) that takes a single parameter and returns a Boolean.
• In this example, we passed lambda expression (item->item.startsWith(“E”)) to the test() function.
• When the filter() method is called on a stream, the filter passed as a parameter to the filter()
function is stored internally.

stream.sort():
• We can sort a stream by calling the sort() method.
• Let’s use the sort() method on the above languages list, as shown in the following code:
languages.stream().sorted().forEach(System.out::println);
• The above method would help sort the elements in alphabetical order.
stream.map():
Stream provides a map() method to map the elements of a stream into another new object. Let’s use the previous example and
convert the elements of the languages list to uppercase, as shown below:
language.stream().map(item->item.uppercase().forEach(System.out::println));
This will map all the elements that are strings in the language collection to their uppercase equivalents.

stream.collect():
Stream API provides a collect() method for processing on the stream interface. When the collect() method is invoked, filtering
and mapping will occur, and the object obtained from those actions will be collected. Let’s take the previous example and obtain
a new list of languages in uppercase, as shown in the below example:
List<String> uase language = languages.stream().map(item>item.toUpperCase()).collect(collectors.toList()));
System.out.println(ucaselanguage);
First, it creates a stream, adds a map to convert the strings to uppercase, and collects all objects in a new list.

stream.min() & max():


The Stream API provides the min() and max() methods to find the min & max values in streams. These methods are used to find
min & max values in different streams like streams of chars, strings, dates, etc. We must change the parameter we pass in this
method based on the stream type.
Stream Operations:
•Intermediate Filtering (filter)
•Mapping (map, flatMap)
•Sorting (sorted)
•Distinct (distinct)
•Limit and Skip (limit, skip)
Intermediate Filtering (filter)
• Think of a stream like a pipeline that allows objects to flow through it.
• Intermediate operations are like valves or filters that can be used to modify
the objects in the pipeline.
• You can use these operations to perform transformations on the objects, such
as mapping them to a new value or filtering out certain objects based on
some condition.
• Other examples of intermediate operations include distinct(), sorted(), and
flatMap().
Method 1: filter(predicate)
It returns a new stream consisting of the elements of the stream from which it is called which are according to
the predicate (condition).
Mapping (map, flatMap)
map() method
• This method takes a Function as an argument and applies it to
each element of the Stream, which will produce a new Stream of
the mapped elements.
• For instance, we can use the map() to convert a Stream of Strings
to a Stream of Integers.
flatMap:
• Java 8 Stream.flatMap() method is used to flatten a Stream of collections to a Stream
of objects.
• During the flattening operation, the objects from all the collections in the original
Stream are combined into a single collection
Stream.flatMap() function to get a single List containing all elements from a list of lists.
This program uses flatMap() operation to convert List<List<Integer>> to List<Integer>.
sorted() method
This method can be used to sort the elements of a stream in ascending order.
Example
The following example illustrates how we can sort the elements of stream in ascending order with the help of
sorted() method.
Sort List In Ascending & Descending Order Using Java Stream API
▪ Java stream provides a method sorted() which can sort List in ascending and
descending order without you to write any complex logic. By default sorting()
method sorts the list in ascending order.
▪ If we want to sort in descending order we need to
pass Comparator.reverseOrder() in sorted() method as a parameter.
distinct() method
• To remove the duplicacy from the elements of a stream, we can use the distinct() method.
• Example
• In this example, we will create a stream with duplicate elements and apply the distinct() method
to print only distinct elements.
•Limit and Skip (limit, skip)

limit() method
The purpose of using limit() method is to restrict the size of output to the specified
limit.
skip() method
We can discard the first n elements from the result using skip() method. It takes an
integer as an argument that specifies those elements which will get discarded.
Example
The following example demonstrates how to use skip() method to discard the first
two elements from the filtered result.
TERMINAL OPERATIONS

• Terminal Operations
• Collecting Results(collect)
• Reducing and Summarizing
• (reduce, summaryStatistics)
• Iterating (forEach)
TERMINAL OPERATIONS
• Collecting Results(collect)
• java.util.stream.Collectors class contains static factory methods which
perform some common reduction operations such as accumulating elements
into Collection, finding min, max, average, sum of elements etc.

• All the methods of Collectors class return Collector type which will be supplied
to collect() method as an argument.
• Reducing Reducing and Summarizing
• (reduce, summaryStatistics)

• In Java, the Stream.reduce() method is used to perform a reduction on the elements of


• a stream using an associative accumulation function
• and returns an Optional.
• It is commonly used to aggregate or combine elements into a single result, such as computing
the maximum, minimum, sum, or product.
•BinaryOperator<T> accumulator: A function that takes two arguments of type T and
returns a result of type T.
•This function is used to accumulate elements.
•T identity: An initial value that is used as the starting point for the reduction.
•Behavior:
•Identity Value: In the second form, the identity value is a starting value.
•It acts as both the initial value and a neutral element in the accumulation process.
•Parameters:
•Accumulation Function: The accumulator function is applied repeatedly to combine the
elements of the stream.
SummaryStatistics:

The summaryStatistics operation in Java Streams is a convenient way to obtain a set


of statistical summaries (such as count, sum, min, average, and max) for a collection of numeric
values. It’s particularly useful for quickly analyzing numeric data.

summarizingInt(), summarizingLong(), summarizingDouble()


These methods return a special class called Int/Long/
DoubleSummaryStatistics which contain statistical information like sum, max,
min, average etc of input elements.
TERMINAL OPERATIONS-II

• Matching and Finding (anyMatch, allMatch, noneMatch,


findFirst, findAny)
• Counting(count).[refer collectors]
Terminal Operations For Finding
There are two terminal operations for finding elements within a
stream,
findAny() which returns an Optional describing some element of the
stream
findAny(): Returns any element from the stream which is useful in
parallel processing.
Stream.findAny() has been introduced for performance gain in the
case of parallel streams, only.
findFirst() which returns an Optional describing the first element of
this stream. Both of these methods return an empty Optional if the
stream is empty.
Matching:
Given a stream of objects, many-a-times we need to check whether object(s) in the given stream
match a specific criteria. Instead of writing logic for iterating over the stream elements and
checking each object whether it matches the criteria (which is more of an imperative rather than
functional style of programming), Java 8 Streams allow declarative matching of objects in the
stream.

I.e. once you define the condition using a Predicate instance, and provide this Predicate as an
input to the matching methods, then Java 8 processes the matching function internally and
provides you with the result whether a match for the condition was found or not.

Java 8 provides such declarative matching with predicate conditions using three methods
defined on the Streams API which are - allMatch(), anyMatch() and noneMatch().
• anyMatch,
• allMatch
• noneMatch
Stream.allMatch() method
• Stream.allMatch() method returns true if all the elements of the stream match the
provided predicate condition.
• If even one of the elements does not match the predicate condition then the method
skips the testing of the remaining elements using the concept of short-circuit
evaluation and returns false as the result.
• This is a terminal stream operation. Definition of allMatch() Method - The
Stream.allMatch() method has the following signature -
• boolean allMatch(Predicate<? super T> predicate)
• Where,
• - input is predicate which is an instance of a Predicate Functional Interface
• - boolean value is returned indicating whether all elements of the stream match
the predicate or not.
Stream.anyMatch() method
Stream.anyMatch() method returns true if at least 1 of the elements of the stream match the provided predicate
condition.
If none of the elements match the predicate condition then the method returns false.
The moment this method finds the first element satisfying the predicate, it skips the testing of the remaining
elements using the concept of short-circuit evaluation and returns true as the result. This is a terminal stream
operation.

Definition of anyMatch() Method - The Stream.anyMatch() method has the following signature -
boolean anyMatch(Predicate<? super T> predicate)
Where,
- input is predicate which is an instance of a Predicate Functional Interface
- boolean value is returned indicating whether any of the elements of the stream match the
predicate or not.

You might also like