0% found this document useful (0 votes)
30 views64 pages

Unit 5 24cs302 Advanced Java Programming

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)
30 views64 pages

Unit 5 24cs302 Advanced Java Programming

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

1

2
Please read this disclaimer before proceeding:
This document is confidential and intended solely for the
educational purpose of RMK Group of Educational Institutions. If you have
received this document through email in error, please notify the system
manager. This document contains proprietary information and is intended
only for the respective group/learning community as intended. If you
are not the addressee you should not disseminate, distribute, or copy
through e-mail. Please notify the sender immediately by e-mail if you
have received this document by mistake and delete this document from
your system. If you are not the intended recipient you are notified that
disclosing, copying, distributing, or taking any action in reliance on
the contents of this information is strictly prohibited.

3
24CS302
Advanced Java Programming
(Lab Integrated)
Department : CSE/IT/ADS/CSD/CSBS/ECE/CSE(CS)
Batch / Year : 2024 – 2028 / II
Created by : All Subject Handling Staff Members
Date : 25.9.2025

4
Table of Contents
Page
[Link]. Topic
No.

1 Course Objectives 6

2 Syllabus 7

3 Pre-requisites 10

4 Course Outcomes 11

5 CO- PO Mapping 12

6 Lecture Plan 13

7 Activity-based learning 14

8 Lecture Notes 15-46

9 Assignments I - V 47- 51

10 Part A Questions & Answers 52

11 Part B Questions 55

12 Supportive Online Certifications 56

13 Real-Time Applications 57

14 Content Beyond the Syllabus 58

15 Assessment Schedule 61

16 Prescribed Text Books & Reference Books 62

17 Mini Projects I - V 63-67

5
1. Course Objectives

OBJECTIVES:
The Course will enable learners to:

 Gain a comprehensive understanding of the Java Collections Framework and its various

interfaces and implementations.

 Learn the details of Java I/O streams and utility classes for managing dates, numbers, and

currencies.

 Develop a thorough understanding of the Stream API introduced in Java 8 and its various

operations.

 Explore advanced object serialization and string tokenizing techniques, including pattern

matching with regular expressions.

 Understand advanced Stream API features and gain proficiency in using regular expressions

for text processing.

6
2. Syllabus
24CS302 ADVANCED JAVA PROGRAMMING (LAB INTEGRATED) L T P C
3 0 3 4.5
UNIT I COLLECTIONS FRAMEWORK AND UTILITY CLASSES 9+9
Introduction to Collections Framework - Collection Interface- Methods in Collection
Interface - Iterable and Iterator Interfaces - List Interface- ArrayList - LinkedList - Set
Interface - HashSet- LinkedHashSet - TreeSet - Map Interface - HashMap -
LinkedHashMap- TreeMap - Queue Interface -PriorityQueue - Deque Interface - Utility
Classes.
List of Experiments
1. Write a program that measures the time taken for insertion, deletion, and search
operations on ArrayList, LinkedList, HashSet, and TreeSet for varying sizes of input
data.
2. Implement a custom data structure that combines features of a list and a set.
3. Write a Java program to create a HashMap where the keys are strings, and the values
are integers Add five key-value pairs to the map. Print all the keys and values in the
map. Remove an entry by key. Update the value associated with a specific key. Check
if the map contains a specific key and a specific value.

UNIT II I/O OPERATIONS, SERIALIZATION, AND DATE HANDLING 9+9


Date – Calendar – Comparable interface – Observer Interface –– Serialization – Dates -
Numbers, and Currency - Working with Dates - Numbers and Currencies - Object
Serialization - Serializable Interface - Writing and Reading Serializable Objects -Transient
Keyword- SerialVersionUID.
List of Experiments
1. Create a class representing a complex object with nested data structures. Serialize the
object to a file, then deserialize it back and verify that the object remains intact.
2. Write a program that formats dates and currencies according to different locales.
3. Create a class hierarchy representing different types of objects (e.g., Person,
Employee). Serialize instances of these classes to a file using object serialization.

7
UNIT III STREAM API AND FUNCTIONAL PROGRAMMING 9+9
PARADIGMS
Overview of Stream API - Importance of Stream API in Java 8 and Beyond – Functional
Programming Concepts - Creating Streams - Stream Interface Methods - Stream
Operations - 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).
List of Experiments
1. Write a program that performs stream operations like filtering, mapping, and
reducing.
2. Create an infinite stream generator that generates prime numbers. Implement
methods to check for primality and generate the next prime number.
3. Write a program that reads a text file containing sentences. Tokenize each sentence
into words, filter out stopwords, and print the remaining words.

UNIT IV ADVANCED STRING PROCESSING, OBJECT SERIALIZATION, 9+9


AND I/O TECHNIQUES
String Tokenizer – Parsing - Tokenizing and Formatting - Locating Data via Pattern
Matching, Tokenizing - Streams - Types of Streams - The Byte-stream I/O hierarchy -
Character Stream Hierarchy – Random Access File class – the [Link]. Console Class -
Advanced I/O - Piped Streams (PipedInputStream and PipedOutputStream) –
SequenceInputStream -PushbackInputStream and PushbackReader.
List of Experiments
1. Write a program that reads a text file and tokenizes it into sentences using the
StringTokenizer class.
2. Implement a java program that allows users to open a text file, navigate through it
using random access, insert, delete, and modify text at specific positions within the file.
3. Implement a program that uses advanced I/O techniques like PipedInputStream,
PipedOutputStream, SequenceInputStream, and PushbackInputStream.

8
UNIT V ADVANCED STREAM FEATURES AND REGULAR EXPRESSIONS 9+9
Importance and Use Cases of Advanced Stream Features - Creating Custom Streams -
Stream Generators ([Link], [Link]) - Infinite Streams - Using
Spliterators – Advanced Stream Operations - FlatMapping - Chaining Stream Operations
- Stream Peeking (peek) - Advanced Filtering Techniques - Introduction to Regular
Expressions - Character Classes - Quantifiers - Pattern Matching - Groups and Capturing
- Regex in Java - [Link] Package Pattern Class - Matcher Class - String
Manipulation with Regex - Splitting Strings - Replacing Text (replaceAll, replaceFirst) -
Replacing with Backreferences.
List of Experiments
1. Implement custom stream generators using [Link] and [Link]
methods.
2. Write a program that demonstrates advanced stream operations like flatMapping,
chaining stream operations, and peeking.
3. Develop a program that utilizes regular expressions to perform string manipulation
tasks such as splitting strings, replacing text, and extracting specific patterns.

TOTAL: 45+45=90 PERIODS

TEXT BOOKS:
1. Cay S. Horstmann, "Core Java Volume I--Fundamentals," 12th Edition, 2019.
2. Joshua Bloch, "Effective Java," 3rd Edition, 2018.
[Link]-Gabriel Urma, "Java 8 in Action: Lambdas, Streams, and Functional-Style
Programming," 1st Edition, 2014. (Java 8 in Action ([Link])

4. Herbert Schildt, "Java: The Complete Reference," 11th Edition, 2018.


5. Alan Mycroft and Martin Odersky, "Programming in Scala," 4th Edition, 2020.

REFERENCES:
1. Bruce Eckel, "Thinking in Java," 4th Edition, 2006.
2. Herbert Schildt, "Java: A Beginner's Guide," 8th Edition, 2019.
3. Richard Warburton, "Java 8 Lambdas: Pragmatic Functional Programming”,
1st Edition, 2014.

9
3. Pre-requisites

24CS302 Advanced Java Programming

22CS202 – Java programming

22CS101 – problem solving using C++

10
4. Course Outcomes
At the end of this course, the students will be able to:

CO# Course Outcomes KL

Utilize the Java Collections Framework to solve complex data structure


CO1 K3
problems..
Demonstrate proficiency in Java I/O operations and manage data
CO2 K3
efficiently.
Learn to utilize the Stream API for complex data processing by applying
CO3 K3
functional programming techniques..

CO4 Understand and implement advanced object serialization techniques. K3

CO5 Effectively use regular expressions for advanced text processing tasks. K3

CO6 Build simple applications using advanced java programming concepts. K3

11
5. CO-PO Mapping

Program Status
Program Outcomes
Course Outcomes
Outcomes PO PO PO PO PO PO PO PO PO PO PO PO PSO PSO PSO
1 2 3 4 5 6 7 8 9 10 11 12 1 2 3
CO1 3 3 3 - - - - - - - - - 3 2 2

CO2 3 2 2 - - - - - - - - - 3 3 2

CO3 3 2 2 - - - - - - - - - 3 3 2

CO4 3 2 2 - - - - - - - - - 3 3 2

CO5 3 2 2 - - - - - - - - - 3 3 2

CO6 3 2 2 - - - - - - - - - 3 3 2

12
6. LECTURE PLAN
Sl. Taxono
No. of. Proposed Actual Pertaining Mode of
No Topics my
. Periods Date Date CO Level Delivery
Introduction to
As per
Collections As per Time
Framework - Time table table MD 1,
1,2 Collection 2 & CO1, CO6 K3
Interface- Methods & MD 4
Academic Academic
in Collection Calendar
Interface Calendar
As per
As per
Time
Time table
Iterable and table MD 1,
3 1 & & CO1,CO6 K3
Iterator Interfaces MD 4
Academic Academic
Calendar Calendar
As per
As per
Time
List Interface- Time table
table MD 1,
4 ArrayList - 1 & & CO1, CO6 K3 MD 4
LinkedList Academic Academic
Calendar Calendar
As per
As per
Set Interface - Time
Time table
HashSet- table MD 1,
5 1 & & CO1, CO6 K3
LinkedHashSet - MD 4
Academic Academic
TreeSet
Calendar Calendar
As per
As per
Map Interface - Time
Time table
HashMap - table MD 1,
6,7 2 & & CO1, CO6 K3
LinkedHashMap- MD 4
Academic Academic
TreeMap
Calendar Calendar
As per
As per
Time
Queue Interface - Time table
table MD 1,
8 PriorityQueue - 1 & & CO1, CO6 K3 MD 4
Deque Interface Academic Academic
Calendar Calendar
As per
As per
Time
Time table
table MD 1,
9 Utility Classes. 1 & & CO1, CO6 K3 MD 4
Academic Academic
Calendar Calendar
As per
As per
Time
10 Time table
table
- Lab Exercises 9 & & CO1, CO6 K3 iamneo
18 Academic Academic
Calendar Calendar
* MD1 – Oral Presentation
13
* MD 4 – Hands on using any Java IDE
7. Activity Based Learning

Common Activities

Learning Methods Activities

Class Exercises, Challenge Yourself,


Learn by Solving Problems Practice At Home exercises posted in
Codetantra Portal

Knowledge Check / MCQ Using


Learn by Questioning
Codetantra portal and RMK Nextgen
App

Learn by Hands on Practice available in Codetantra Portal

Unit V Activity : -Puzzle Activity

Crossword Puzzle Sheet


Topic: Advanced Streams, Spliterators, and Regex

14
Crossword Puzzle Clues

Across
A stream operation that flattens nested lists into a single stream. (7 letters)

A regex class in Java used to compile patterns. (7 letters)

A stream operation used for intermediate debugging/logging. (4 letters)

A regex symbol that matches zero or more occurrences. (1 letter)

A Java class used to apply regex patterns on text. (7 letters)

Down

A regex construct used to capture repeating groups. (12 letters)

A method used to create an infinite stream of generated elements. (8 letters)

A Java interface used to split data for parallel stream processing. (11 letters)

A regex symbol that matches exactly one occurrence or none. (1 letter)

A method in Streams used to restrict an infinite stream to a finite size. (5 letters)

1 2 3 4 5 6 7 8 9 10
A__________
B__________
C__________
D__________
E__________
F__________
G__________
H__________
I__________
J__________

15
8. Lecture Notes
5.1 Importance and Use Cases of Advanced Stream Features :

Java’s Stream API, introduced in Java 8, has significantly enhanced how developers handle collections
and data processing. Here are some key points on the importance and use cases of advanced stream
features:
Efficiency and Performance: Streams allow for efficient data processing by enabling operations like
filtering, mapping, and reducing without the need for explicit loops.
Parallel Processing: Streams support parallel execution, which can significantly improve performance
for large datasets by leveraging multi-core processors.
Functional Programming: Streams promote a functional programming style, which can lead to more
predictable and maintainable code by avoiding mutable state and side effects.
Expressiveness: The Stream API provides a rich set of operations that can be combined in a fluent
manner, making the code more expressive and easier to understand.
Use Cases of Advanced Stream Features

[Link] Transformation: Streams can be used to transform data from one form to another. For
example, converting a list of stings to uppercase:
List<String> upperCaseNames = [Link]()
.map(String::toUpperCase)
.collect([Link]());
2. Filtering Data: Streams make it easy to filter data based on certain criteria. For instance, filtering
out even numbers from a list:

List<Integer> oddNumbers = [Link]()


.filter(n -> n % 2 != 0)
.collect([Link]());
[Link] Operations: Streams support aggregation operations like sum, average, and count.
For example, calculating the sum of a list of integers:

int sum = [Link]()


.mapToInt(Integer::intValue)
.sum();

16
8. Lecture Notes
[Link] Processing: Streams can be processed in parallel to improve performance. For

example, summing a large list of integers in parallel:

Java
int parallelSum = [Link]()
.mapToInt(Integer::intValue)
.sum();
[Link] Data Pipelines: Streams can be used to create complex data processing pipelines.

For example, filtering, mapping, and collecting data in a single pipeline:

Java
List<String> result = [Link]()
.filter(d -> [Link]("A"))
.map(String::toLowerCase)
.collect([Link]());
 Java's stream API, introduced in Java 8, has become a powerful tool for processing sequences of
elements in a declarative and functional style. Advanced stream features enhance this capability,
offering more flexibility, performance, and expressiveness in handling data collections.

1. 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.

2. 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.
8. Lecture Notes
3. Lazy Evaluation
 Importance: Streams in Java are lazily evaluated, meaning that operations on streams are
only executed when a terminal operation is invoked. This can lead to performance
optimizations.

 Use Cases:
 Efficient Data Pipelines: Building pipelines that only process as much data as needed, for
example, finding the first match in a large dataset.
 Resource Management: Minimizing resource usage by processing data on-demand rather
than upfront, such as reading lines from a large file only as needed.

4. 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.

5. 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.

6. 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.
8. Lecture Notes
5.2 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. This process typically involves the use of
Spliterator, [Link], or [Link] methods.

 Steps to Create Custom Streams in Java:


1. Using [Link]() and [Link]()
[Link](): Creates a stream from a specified set of elements.
[Link]: Useful when you need to build a stream step by step.
Stream<String> stream = [Link]("apple", "banana", "cherry");

Stream<String> builtStream = Stream.<String>builder() .add("apple") .add("banana") .add("cherry")


.build();
2. Using [Link]()
[Link](): Creates an infinite stream where each element is generated using a Supplier function.
Stream<Double> randomNumbers = [Link](Math::random).limit(10);

3. Using [Link]()
[Link](): Creates an infinite stream where each element is produced by applying a function to the
previous element.

Stream<Integer> evenNumbers = [Link](0, n -> n + 2).limit(10);


4. Creating Streams from Custom Data Structures
You can create streams from custom data structures by implementing a custom Spliterator.
class CustomSpliterator implements Spliterator<Integer> {

private final int[] array;


private int index = 0;
public CustomSpliterator(int[] array) {
[Link] = array;

}
@Override
public boolean tryAdvance(Consumer<? super Integer> action) {
if (index < [Link]) {

[Link](array[index++]);
return true;
}
return false;
}
8. Lecture Notes
@Override
public Spliterator<Integer> trySplit() {
int length = [Link] - index;
if (length <= 1) return null;
int splitIndex = length / 2 + index;
Spliterator<Integer> spliterator = new CustomSpliterator([Link](array, index,
splitIndex));
index = splitIndex;
return spliterator;
}
@Override
public long estimateSize() {
return [Link] - index;

}
@Override
public int characteristics() {
return SIZED | SUBSIZED | ORDERED;
}
}
public class CustomStream {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5};
Spliterator<Integer> spliterator = new CustomSpliterator(array);
Stream<Integer> stream = [Link](spliterator, false);
[Link]([Link]::println);

}
}
8. Lecture Notes
5.3 Infinite Streams
 In Java, an infinite stream is a stream that produces an unbounded number of elements, which
means it has no predefined limit.
 You typically create infinite streams when you need to generate an endless sequence of elements
or a sequence that depends on some continuous conditions, like random numbers or the Fibonacci
series.
 There are mainly two methods defined in the Stream class to create infinite streams and both are
static methods defined in the Stream class.
 Java's Stream API provides ways to create infinite streams using methods like [Link]()
and [Link]().
 [Link](): This method creates an infinite stream where each element is
generated using a Supplier. The supplier function is invoked to produce each element, and the
stream doesn't stop unless you limit it manually.
static <T> Stream<T> generate(Supplier<T> s)
Stream<Double> randomNumbers = [Link](Math::random);
[Link](5).forEach([Link]::println);

In this example, we generate an infinite stream of random numbers but limit it to 5 elements
using limit().

 2. [Link]() : This method generates an infinite stream where each element is generated
based on the previous one. You provide an initial seed (starting value) and a unary operator that
computes the next value from the previous one.
static <T> Stream<T> iterate(T seed,UnaryOperator<T> fn)
Stream<Integer> evenNumbers = [Link](0, n -> n + 2);
[Link](5).forEach([Link]::println);

 This example generates numbers from 1 to 10, effectively making it a finite stream.
Use Cases:
 Random number generation: Infinite streams are helpful when you need to continuously
generate random data.
 Fibonacci sequence: A classic example where infinite streams can be used to generate the
Fibonacci sequence.

 Date/time sequence generation: You can create streams of incrementing dates or timestamps.
8. Lecture Notes
Example: Infinite Fibonacci Sequence:
import [Link];
import [Link]; // For holding two values together

public class FibonacciStream {


public static void main(String[] args) {
// Creating an infinite stream of Fibonacci numbers using a Pair to hold two consecutive
numbers
[Link](new Pair<>(0, 1), p -> new Pair<>([Link](), [Link]() +
[Link]()))
.limit(10) // Limit the stream to 10 Fibonacci numbers
.forEach(p -> [Link]([Link]()));
}
}
Spliterators
 A Spliterator in Java is a specialized iterator designed for parallel processing of data
streams. It splits the data structure into smaller parts, allowing multiple threads to process
different chunks concurrently. Spliterators are the backbone of how streams, especially
parallel streams, work efficiently. They are particularly useful for optimizing performance in
large data sets.

 Spliterator is an advanced feature used when you need control over how your data is
divided and processed in parallel streams. Java's collection classes (e.g., ArrayList, HashSet)
come with built-in spliterators that are tuned for optimal performance.

Key Methods of Spliterator


 trySplit(): Attempts to split the data into two parts. If successful, one part is processed by
the current thread, and the other can be processed by a new thread.
 tryAdvance(): Processes one element at a time, similar to an iterator.
 characteristics(): Provides metadata about the underlying data, such as whether it is sorted
or immutable.
Creating a Custom Spliterator
You can create a custom Spliterator if you want full control over how data is split for parallel
processing. Here’s a simple example where a custom spliterator is created to handle an array
of integers.
8. Lecture Notes
Example: Custom Spliterator
import [Link];
import [Link];
public class ArraySpliterator implements Spliterator<Integer> {
private final int[] array;

private int start;


private int end;
public ArraySpliterator(int[] array, int start, int end) {
[Link] = array;

[Link] = start;
[Link] = end;
}
@Override
public boolean tryAdvance(Consumer<? super Integer> action) {
if (start < end) {
[Link](array[start++]);
return true;

}
return false;
}

@Override
public Spliterator<Integer> trySplit() {
int length = end - start;

if (length <= 1) {
return null; // No more splits possible
}
8. Lecture Notes
int mid = start + length / 2;
Spliterator<Integer> newSpliterator = new ArraySpliterator(array, start, mid);
start = mid; // Adjust the current spliterator to the second half
return newSpliterator;
}
@Override
public long estimateSize() {
return end - start;

}
@Override
public int characteristics() {
return ORDERED | SIZED | SUBSIZED;
}
}

5.4 Advanced Stream Operations :


 The Stream interface in [Link] defines many operations. They can be
classified into two categories. Let’s look at our previous example once again:

Fig 5.1 Java Streams Operations


8. Lecture Notes
Various Core Operations Over Streams:
There are broadly 3 types of operations that are carried over streams namely as follows as
depicted from the image shown above:

 Intermediate operations
 Terminal operations
 Short-circuit operations

Java Streams API offers many advanced operations to manipulate and process data efficiently. Let's
explore some of the more advanced stream operations beyond basic ones like map(), filter(), and
forEach().

flatMap():
flatMap() is used when you have a stream of collections (e.g., lists, arrays) and you want to flatten
them into a single stream. It helps in transforming nested structures into a flat structure.
List<List<String>> namesList = [Link](
[Link]("John", "Jane"),

[Link]("Tom", "Jerry"),
[Link]("Alice", "Bob")
);

List<String> flatNames = [Link]()


.flatMap(List::stream) // Flatten the nested lists into a single stream
.collect([Link]());
[Link](flatNames);
8. Lecture Notes

 reduce(): reduce() performs a reduction on the elements of the stream using an associative
accumulation function. It helps in reducing the stream elements into a single result, such as
summing or concatenating values.

List<Integer> numbers = [Link](1, 2, 3, 4, 5);


int sum = [Link]()
.reduce(0, (a, b) -> a + b); // Start with 0 and sum all the numbers

[Link]("Sum: " + sum);

 collect() with Custom Collectors: While collect() is commonly used with built-in collectors
like [Link]() or [Link](), you can also define custom collectors to perform
more advanced operations.

List<String> words = [Link]("apple", "banana", "cherry", "date", "elderberry");

Map<Integer, List<String>> groupedByLength = [Link]()


.collect([Link](String::length));

[Link](groupedByLength);

 peek(): peek() is used for debugging or intermediate actions during stream processing. It
allows you to perform an action on each element as it's passed through, without modifying the
elements.
List<String> names = [Link]("John", "Jane", "Tom", "Jerry");
[Link]()

.filter(name -> [Link]("J"))


.peek(name -> [Link]("Filtered: " + name)) // Log the filtered names
.map(String::toUpperCase)
.forEach([Link]::println);
 partitioningBy(): partitioningBy() is a specialized collector that partitions a stream into two
groups based on a predicate. It creates a Map<Boolean, List<T>>, where the key is true for
elements that match the predicate and false for those that don't.
8. Lecture Notes
 partitioningBy(): partitioningBy() is a specialized collector that partitions a stream into two groups
based on a predicate. It creates a Map<Boolean, List<T>>, where the key is true for elements that
match the predicate and false for those that don’t.
List<Integer> numbers = [Link](1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Map<Boolean, List<Integer>> partitioned = [Link]()

.collect([Link](n -> n % 2 == 0)); // Partition by even numbers

[Link](partitioned);
 skip() and limit(): These operations are often combined to implement pagination or selective data
[Link](n): Skips the first n [Link](n): Limits the stream to the first n elements.
List<String> items = [Link]("item1", "item2", "item3", "item4", "item5", "item6");

List<String> page2 = [Link]()


.skip(3) // Skip the first 3 elements
.limit(3) // Limit to the next 3 elements
.collect([Link]());
[Link](page2);

 groupingBy(): groupingBy() is a powerful collector used to group elements in a stream by a classifier


function. It creates a Map<K, List<T>>, where K is the grouping key, and List<T> is the list of
elements in each group.
List<String> names = [Link]("John", "Jane", "Tom", "Jerry", "Alice", "Bob");
Map<Character, List<String>> groupedByFirstLetter = [Link]()
.collect([Link](name -> [Link](0)));
[Link](groupedByFirstLetter);
 collectingAndThen(): This collector transforms the result of another collector. It allows you to post-
process the result after collection.
List<String> names = [Link]("John", "Jane", "Tom");
List<String> unmodifiableNames = [Link]()
.collect([Link](
[Link](),
Collections::unmodifiableList

));
[Link](unmodifiableNames);
8. Lecture Notes
 Parallel Streams: Parallel Streams can run stream operations in parallel using
.parallelStream(). However, it should be used carefully for operations that are CPU-bound and
where the ordering of elements isn't important.
List<Integer> numbers = [Link](1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = [Link]()

.reduce(0, Integer::sum);
[Link]("Sum: " + sum);
Collect():
 The collect() method in Java Streams is a terminal operation used to transform the
elements of a stream into a different form, usually a collection (like a List, Set, or Map), or
to perform some kind of aggregation (such as summing or concatenating elements).
 It is extremely flexible and can be customized to suit various requirements using
predefined or custom collectors.
<R, A> R collect(Collector<? super T, A, R> collector);
Where:
T is the type of elements in the stream.
A is the type of the accumulator used in the collector (intermediate data).
R is the type of the result (e.g., List, Set, Map).
 Joining Strings: we can concatenate the elements of a stream into a single string using
[Link]().
String concatenated = [Link]("Alice", "Bob", "Charlie")
.collect([Link](", "));
[Link](concatenated);

 Collecting into a Map: We can collect elements into a Map using [Link]().
The key and value can be determined by mapping functions.

Map<String, Integer> nameLengthMap = [Link]("Alice", "Bob", "Charlie")


.collect([Link](name -> name, name -> [Link]()));
[Link](nameLengthMap);

 Grouping BygroupingBy() is a powerful collector that groups elements based on a


classifier function. The result is a Map<K, List<T>>, where K is the key type (grouping
criterion), and List<T> is the list of elements in each group.
8. Lecture Notes

Map<Integer, List<String>> groupedByLength = [Link]("Alice", "Bob", "Charlie", "David")


.collect([Link](String::length));
[Link](groupedByLength);

 Summing and Averaging:


 The [Link](), [Link](), and other similar collectors can be used to
perform numerical aggregations.
Summing integersjavaCopy codeint sum = [Link](1, 2, 3, 4, 5)
.collect([Link](Integer::intValue));[Link]("Sum: " + sum);

5.5 Chaining Stream Operations:


 We can chain together several building-block operations to express a complicated data processing
pipeline (you chain the filter by linking sorted, map, and collect operations, as illustrated in figure 5.2)
while keeping your code readable and its intent clear.
 The result of the filter is passed to the sorted method, which is then passed to the map method and
then to the collect method.
 Because operations such as filter (or sorted, map, and collect) are available as high-level building blocks
that don’t depend on a specific threading model, their internal implementation could be single-threaded
or potentially maximize your multicore architecture transparently

Fig 5.2 Chaining stream operations forming a stream pipeline


8. Lecture Notes
Key Concepts in Chaining Stream Operations:
 Intermediate Operations: These are operations that transform a stream into another stream.
 They are lazy, meaning they are not executed until a terminal operation is invoked
Examples: filter(), map(), sorted(), distinct(), limit(), etc.
 Terminal Operations: These are operations that produce a result or a side effect from the
stream. They trigger the processing of the data in the stream pipeline.
Examples: collect(), forEach(), reduce(), count(), findFirst(), etc.
Example:
import [Link];
import [Link];

import [Link];

public class StreamChainingExample {


public static void main(String[] args) {
List<String> names = [Link]("John", "Paul", "George", "Ringo", "john");
List<String> filteredNames = [Link]()

.map(String::toLowerCase) // Convert each name to lowercase


.filter(name -> [Link]("j")) // Filter names that start with "j"
.distinct() // Ensure names are unique
.sorted() // Sort the names
.collect([Link]()); // Collect the result into a List

[Link](filteredNames); // Output: [john]


}
}
8. Lecture Notes
Breakdown of Operations:
. map(String::toLowerCase) – Converts each name to lowercase
.filter(name -> [Link]("j")) – Filters names that start with the letter "j“
.distinct() – Removes duplicates
.sorted() – Sorts the names alphabetically
.collect([Link]()) – Collects the results into a list.

Benefits of Chaining Stream Operations


Readability: The declarative style of streams makes the code easier to read and understand.
Lazy Evaluation: Intermediate operations are not executed until a terminal operation is called.
This can lead to performance optimizations, especially when working with large datasets.
Immutability: Stream operations do not modify the source, leading to more predictable and safe code.
import [Link];
import [Link];
import [Link];
public class StreamPeekExample {

public static void main(String[] args) {


List<String> names = [Link]("Alice", "Bob", "Charlie", "David");
List<String> result = [Link]()

.filter(name -> [Link]() > 3) // Filter names longer than 3 characters


.peek(name -> [Link]("Filtered: " + name)) // Inspect filtered names
.map(String::toUpperCase) // Convert names to uppercase
.peek(name -> [Link]("Mapped: " + name)) // Inspect mapped names
.collect([Link]()); // Collect the result into a List
[Link]("Final result: " + result);

}}
Output:
Filtered: Alice
Filtered: Charlie
Filtered: David
Mapped: ALICE
Mapped: CHARLIE
Mapped: DAVID

Final result: [ALICE, CHARLIE, DAVID]


8. Lecture Notes

Stream Peeking (peek)


 in JavaThe peek() method in Java's Stream API is an intermediate operation that allows you to
inspect elements of the stream as they flow through the pipeline without modifying the elements.
This is useful for debugging or for logging intermediate values in a stream.
 The peek() method can be thought of as a side-effect operation, meaning it performs a non-
intrusive action (like printing, logging, or updating metrics) without changing the elements
themselves.
Stream<T> peek(Consumer<? super T> action)

[Link]("apple", "banana", "orange")


.filter(fruit -> [Link]("a"))
.peek(fruit -> [Link]("Filtered value: " + fruit))
.map(String::toUpperCase)
.peek(fruit -> [Link]("Mapped value: " + fruit))
.forEach([Link]::println);
Filtered value: apple

Mapped value: APPLE


APPLE

Advanced Filtering Techniques:


 filter method in Java Streams is used to filter elements based on a predicate, with the syntax
List<dataType> output = [Link]().filter(unfilteredList ->
[Link]());.

 It’s a powerful tool that allows you to sift through data and extract what you need.

List<String> names = [Link]('John', 'Susan', 'Kim', 'George');


List<String> result = [Link]().filter(name ->
[Link]('J')).collect([Link]());

// Output:
// [John]
 This is just a basic usage of the Java Stream filter method. But there’s so much more you can do
with it, including chaining multiple filters and using complex predicates. Continue reading for a
more detailed explanation and advanced usage scenarios.
8. Lecture Notes
Advanced Techniques with Java Stream Filter:
Chaining Multiple Filters:
List<Integer> numbers = [Link](1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> result = [Link]()

.filter(n -> n % 2 == 0)
.filter(n -> n > 5)
.collect([Link]());
// Output:
// [6, 8, 10]

 First filter out the even numbers, and then we filter out the numbers that are greater than 5. The
result is a list of even numbers greater than 5.

 You can combine multiple conditions using logical operators (e.g., &&, ||) in the filter() method.
import [Link];
import [Link];
public class MultiConditionFilter {
public static void main(String[] args) {
List<String> names = [Link]("John", "Paul", "George", "Ringo");
List<String> filteredNames = [Link]()

.filter(name -> [Link]() > 4 && [Link]("G"))


.collect([Link]());
[Link](filteredNames); // Output: [George]
}
}
Using Complex Predicates:
A predicate is a function that takes an input and returns a boolean value.
List<String> names = [Link]('John', 'Susan', 'Kim', 'George');
List<String> result = [Link]()

.filter(name -> [Link]('J') && [Link]() > 3)


.collect([Link]());

// Output:
// [John]
8. Lecture Notes
Using Loops for Filtering
List<Integer> numbers = [Link](1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = new ArrayList<>();

for (Integer number : numbers) {


if (number % 2 == 0) {
[Link](number);
}
}
// Output:
// evenNumbers: [2, 4, 6, 8, 10]
The Real-World Application of Java Stream Filter:
 Stream filter is not just a theoretical concept; it has practical applications in real-world
scenarios. Let’s explore a few of these applications and how the filter method can be a game-
changer.

Java Stream Filter in Data Processing


 Data processing is one area where Java Stream filter shines. Whether you’re dealing with large
datasets or small, the filter method can help you sift through and extract the data you need.
It’s a much more efficient and readable alternative to traditional loops.

Leveraging Java Stream Filter for File I/O


 File I/O operations often involve reading data, processing it, and writing the results back to a
file. The filter method can be used to process the data read from the file, such as filtering out
unwanted lines or extracting specific information.

Other Stream Operations and Parallel Streams


 The filter method is just one of many operations available in Java Streams. Other operations
like map, reduce, and collect can be combined with filter to perform complex data processing
tasks. Moreover, Java Streams support parallel processing, which can significantly improve
performance for large datasets.
8. Lecture Notes
Introduction to Regular Expressions:

 The Java Regex or Regular Expression is an API to define a pattern for searching or
manipulating strings.
 It is widely used to define the constraint on strings such as password and email validation. After
learning Java regex tutorial, you will be able to test your regular expressions by the Java Regex
Tester Tool.
 Java Regex API provides 1 interface and 3 classes in [Link] package.
 The Matcher and Pattern classes provide the facility of Java regular expression. The
[Link] package provides following classes and interfaces for regular expressions.
 MatchResult interface
 Matcher class
 Pattern class
 PatternSyntaxException class
Matcher class
It implements the MatchResult interface. It is a regex engine which is used to perform match
operations on a character sequence.
No. Method Description
1 boolean matches() test whether the regular expression matches the pattern.
2 boolean find() finds the next expression that matches the pattern.
3 boolean find(int start) finds the next expression that matches the pattern from the
given start number.
4 String group() returns the matched subsequence.
5 int start() returns the starting index of the matched subsequence.
6 int end() returns the ending index of the matched subsequence.
7 int groupCount() returns the total number of the matched subsequence.
8. Lecture Notes
Character Classes :

 In the context of regular expressions, a character class is a set of characters enclosed within
square brackets. It specifies the characters that will successfully match a single character from a
given input string.

 Regular expressions (also called “Regex”) are special types of pattern-matching strings that
describe a pattern in a text. A regex can be matched against another string to see whether the
string fits the pattern. In general, regex consists of normal characters, character classes, wildcard
characters, and quantifiers.
 At times there’s a need to match any sequence that contains one or more characters, in any
order, that is part of a set of characters. For example, to match whole words, we want to match
any sequence of the letters of alphabets.
 Character classes come in handy for such use-cases. A character class is a set of characters such
that characters are put between square brackets ‘[‘ and ‘]’. For example, class [abc] matches a, b,
c characters.
 A range of characters can also be specified using hyphens. For example, to match whole words of
lowercase letters, the [a-z] class can be used.
 Note that a character class has no relation with a class construct or class files in Java. Also, the
word “match” means a pattern exists in a string, it does not mean the whole string matches the
pattern. A regex pattern lets us use two types of character classes:
• Predefined character classes and
• Custom character classes
Predefined Character Classes
 Some frequently used character classes are predefined in Java, these are listed below. Characters
in these classes are usually proceeded with a backslash “\” and need not reside in brackets “[”
and “]”.
8. Lecture Notes

Predefined
Meaning of predefined character classes
character classes

This special character dot (.) matches any character. One dot matches one

(.dot) (any) character, two dots match two characters and so on. Dot characters
may or may not match line terminators.

This matches any digit character. This works the same as the character
\d
class [0-9].

This matches any character except for digits. This works the same as the
\D
character class [^0-9].

This matches any whitespace character. This includes a space ‘ ‘, a tab ‘\t’,
\s a new line ‘\n’, a vertical tab ‘\x0B’, a form feed ‘\f’, a carriage return ‘\r’
and backspace character ‘\b’.

This matches any character except for the whitespace characters listed
\S
above.

This matches any word character, including both uppercase and lowercase,
\w also including digit characters and the underscore character ‘_’. This works
the same as the class [a-zA-z_0-9].

This matches any character except for word characters. This works the
\W
same as the class [^a-zA-z_0-9].
8. Lecture Notes
Custom Character Classes:

Example of custom
character class Meaning of the custom character class

This regex means pattern must start with “b” followed by any of the
vowels “a”, “e”, “i”, “o”, “u” followed by “t”.
b[aeiou]t
Strings “bat”, “bet”, “bit”, “bot”, “but” would match this regex, but “bct”,
“bkt”, etc. would not match.

Such a regex can be used to allow uppercase letters too in the previous
[bB][aAeEiIoOuU][tT]
regex. So the strings “bAT”, “BAT”, etc. would match the pattern.

“^” at the beginning of character class works as negation or


complement, such that this regex means any character other than
vowels is allowed between “b” and “t”. Strings “bct”, “bkt”, “b+t”, etc.
b[^aeiou]t
would match the pattern. Using a ‘^’ at the beginning of character class
has a special meaning, but using ‘^’ anywhere in the class apart from at
the beginning, acts like any other normal character.

Range of letters and digits can be specified in character classes using the
[a-z][0-3] hyphen “-“. Strings “a1”, “z3”, etc. match the pattern. Strings “k7”, “n9”,
etc. does not match.

More than one range can be used in a class. Strings “A1”, “b2”, etc.
[a-zA-Z][0-9]
match the pattern.

Nesting character classes simply add them, so this class is the same as
[A-F[G-Z]]
[A-Z] class.

Intersection of ranges also works in character classes. This regex means


[a-p&&[l-z]] characters “l”, “m”, “n”, “o”, “p” would match in a string.

Subtraction of ranges also works in character classes. This regex means


[a-z&&[^aeiou]] vowels are subtracted from the range “a-z”.
8. Lecture Notes
Quantifiers:
 Quantifiers can be used in character classes. Using quantifiers we can specify the number of
times a character in a regex may match the sequence of characters.

Quantifiers Meaning of the quantifier

* Zero or more times

Placing an asterisk “*” after a character class means “allow any number of occurrences of
that character class”. For example, “0*\d” regex matches any number of leading zeroes
followed by a digit.

+ One or more times

“+” plus sign has the same effect as XX*, meaning a pattern followed by pattern asterisk.
For example, “0+\d” regex matches at least one leading zeroes followed by a digit.

? zero or one time

“?” question mark sign allows either zero or one occurrence. For example, “\w\w-?\d\d”
regex matches 2-word characters followed by an optional hyphen and then followed by 2
digit characters.

{m} Exactly “m” times

{m, } At least “m” times

{m, n} At least “m” times and at most “n” times

Pattern Matching:

Pattern Class
This class is a compilation of regular expressions that can be used to define various
types of patterns, providing no public constructors. This can be created by invoking the
compile() method which accepts a regular expression as the first argument, thus
returning a pattern after execution.
8. Lecture Notes
Pattern Class Methods:

S.
No. Method Description

It is used to compile the given regular


1. compile(String regex)
expression into a pattern.

It is used to compile the given regular


2. compile(String regex, int flags) expression into a pattern with the given flags.

3. flags() It is used to return this pattern’s match flags.

It is used to create a matcher that will match


4. matcher(CharSequence input) the given input against this pattern.

It is used to compile the given regular


matches(String regex,
5. expression and attempts to match the given
CharSequence input)
input against it.

It is used to return the regular expression from


6. pattern() which this pattern was compiled.

It is used to return a literal pattern String for the


7. quote(String s) specified String.

It is used to split the given input sequence


8. split(CharSequence input)
around matches of this pattern.

It is used to split the given input sequence


split(CharSequence input, int around matches of this pattern. The limit
9. limit) parameter controls the number of times the
pattern is applied.

It is used to return the string representation of


10. toString()
this pattern.
8. Lecture Notes
// Java Program Demonstrating Working of matches() Method
// Pattern class

// Importing Pattern class from [Link] package


import [Link];

// Main class
class GFG {

// Main driver method


public static void main(String args[])
{

// Following line prints "true" because the whole


// text "geeksforgeeks" matches pattern
// "geeksforge*ks"

[Link]([Link](

"geeksforge*ks", "geeksforgeeks"));

// Following line prints "false" because the whole


// text "geeksfor" doesn't match pattern "g*geeks*"
[Link](
[Link]("g*geeks*", "geeksfor"));
}

Output
true
false
8. Lecture Notes
Matcher class

This object is used to perform match operations for an input string in Java, thus interpreting the
previously explained patterns. This too defines no public constructors. This can be implemented by
invoking a matcher() on any pattern object.

S. No. Method Description

It is mainly used for


searching multiple
1. find() occurrences of the
regular expressions in
the text.

It is used for searching


occurrences of the
2. find(int start) regular expressions in
the text starting from
the given index.

It is used for getting the


start index of a match
3. start() that is being found
using find() method.

It is used for getting the


end index of a match
that is being found
4. end() using find() method. It
returns the index of the
character next to the
last matching character.

It is used to find the


5. groupCount() total number of the
matched subsequence.

It is used to find the


6. group() matched subsequence.

It is used to test
whether the regular
7. matches() expression matches the
pattern.
8. Lecture Notes

Java program to demonstrate working of


// String matching in Java

// Importing Matcher and Pattern class


import [Link];
import [Link];

// Main class
class GFG {

// Main driver method


public static void main(String args[])
{
// Create a pattern to be searched
// Custom pattern
Pattern pattern = [Link]("geeks");

// Search above pattern in "[Link]"


Matcher m = [Link]("[Link]");

// Finding string using find() method


while ([Link]())

// Print starting and ending indexes


// of the pattern in the text
// using this functionality of this class
[Link]("Pattern found from "
+ [Link]() + " to "
+ ([Link]() - 1));
}
}
Output
Pattern found from 0 to 4
Pattern found from 8 to 12

Capturing Groups
Capturing groups are a way to treat multiple characters as a single unit. They are created
by placing the characters to be grouped inside a set of parentheses.
For example, the regular expression (dog) creates a single group containing the letters "d",
"o", and "g".
Capturing groups are numbered by counting their opening parentheses from the left to the
right. In the expression ((A)(B(C))), for example, there are four such groups −
((A)(B(C)))
(A)
(B(C))
(C)
8. Lecture Notes
 To find out how many groups are present in the expression, call the groupCount method on a
matcher object. The groupCount method returns an int showing the number of capturing
groups present in the matcher's pattern.
 There is also a special group, group 0, which always represents the entire expression. This
group is not included in the total reported by groupCount.

Example
Following example illustrates how to find a digit string from the given alphanumeric string −
import [Link];

import [Link];

public class RegexMatches {

public static void main( String args[] ) {


// String to be scanned to find the pattern.
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";

// Create a Pattern object


Pattern r = [Link](pattern);

// Now create matcher object.


Matcher m = [Link](line);
if ([Link]( )) {
[Link]("Found value: " + [Link](0) );
[Link]("Found value: " + [Link](1) );

[Link]("Found value: " + [Link](2) );


}else {
[Link]("NO MATCH");
}
}
}
Output
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0
8. Lecture Notes
String Manipulation with Regex
Extract Substrings Using Groups:
import [Link];
import [Link];

public class RegexGroupExample {


public static void main(String[] args) {

String text = "John Doe was born on 1995-06-15.";


String regex = "(\\d{4})-(\\d{2})-(\\d{2})"; // Capture year, month, and day

Pattern pattern = [Link](regex);


Matcher matcher = [Link](text);

if ([Link]()) {
[Link]("Year: " + [Link](1)); // Output: Year: 1995
[Link]("Month: " + [Link](2)); // Output: Month: 06
[Link]("Day: " + [Link](3)); // Output: Day: 15
}
}
}

Split Strings Using Regex:

import [Link];
public class RegexSplitExample {
public static void main(String[] args) {
String text = "apple,banana;orange|grape";
String regex = "[,;|]"; // Match commas, semicolons, or pipes

Pattern pattern = [Link](regex);


String[] fruits = [Link](text);

for (String fruit : fruits) {


[Link](fruit); // Output: apple, banana, orange, grape
}
}
}
8. Lecture Notes

Replacement Methods :

[Link]
Method & Description
.

public Matcher appendReplacement(StringBuffer sb, String


1 replacement)
Implements a non-terminal append-and-replace step.

public StringBuffer appendTail(StringBuffer sb)


2
Implements a terminal append-and-replace step.

public String replaceAll(String replacement)


3 Replaces every subsequence of the input sequence that matches the pattern
with the given replacement string.

public String replaceFirst(String replacement)


4 Replaces the first subsequence of the input sequence that matches the pattern
with the given replacement string.

public static String quoteReplacement(String s)


Returns a literal replacement String for the specified String. This method
5
produces a String that will work as a literal replacement s in the
appendReplacement method of the Matcher class.

The replaceFirst() and replaceAll() Methods:

import [Link];
import [Link];

public class RegexMatches {

private static String REGEX = "dog";


private static String INPUT = "The dog says meow. " + "All dogs say meow.";
private static String REPLACE = "cat";

public static void main(String[] args) {


Pattern p = [Link](REGEX);

// get a matcher object


Matcher m = [Link](INPUT);
INPUT = [Link](REPLACE);
[Link](INPUT);
}
}
8. Lecture Notes
 The replaceFirst() method in Java is part of the String class, and it is used for replacing the first
occurrence of a substring that matches a regular expression (regex) pattern. Unlike replaceAll(),
which replaces all matches of the pattern, replaceFirst() only replaces the first match it finds.
String text = "hello world, hello Java!";
String result = [Link]("hello", "Hi");
[Link](result);

 Output: Hi world, hello Java!

Replacing with backreferences:


 Replacing with backreferences in Java involves using captured groups from a regular expression
and reusing them in the replacement string. Backreferences allow you to refer to specific groups
matched in the regex during a replaceAll() operation, making it easy to reorder or modify parts
of the original string while keeping certain parts intact.I
 n Java, backreferences are represented by $1, $2, etc., where the number corresponds to the
group number in the regular expression.

Example:
import [Link];
import [Link];
public class DateFormatReplace {
public static void main(String[] args) {
String date = "2023-10-02";

String regex = "(\\d{4})-(\\d{2})-(\\d{2})"; // Capture year, month, and day

// Reorder using backreferences $2 for month, $3 for day, and $1 for year
String replacement = "$2/$3/$1";

Pattern pattern = [Link](regex);


Matcher matcher = [Link](date);

String formattedDate = [Link](replacement);


[Link](formattedDate); // Output: 10/02/2023

}
}
9. Assignment - I

1. Write a Java program to create a custom stream of 10 random integers between 1 and 100
using [Link](). Then filter out numbers greater than 50 and display the remaining
numbers.

2. Use [Link]() to generate the first 10 even numbers. Print the generated stream
elements.

3. Create an infinite stream of random decimal numbers using [Link](). Use the limit()
method to restrict it to the first 20 numbers and then print them.

4. Given a list of strings, write a Java program to filter out strings starting with the letter ‘A’ and
having more than 5 characters using multiple filter() operations.

5. Write a program that flattens a List<List<Integer>> using flatMap() and converts it into a single
list of integers. Print the result.

48
9. Assignment - II

1. Create a list of numbers from 1 to 20. Using stream operations, filter out even numbers,
but use the peek() method to log each number as it passes through the stream before
printing the filtered numbers.

2. Write a program that takes an input string and uses regex to replace all occurrences of
multiple spaces with a single space. Also, remove any leading or trailing spaces.

3. Given a paragraph of text, use a regular expression to split the paragraph into sentences.
Consider punctuation marks like ., !, and ? as sentence delimiters.

4. Write a program that uses regex to find all email addresses in a given text file. The email
addresses should match the pattern username@[Link] and should be displayed
on the console.

5. Write a Java program that uses regex with backreferences to find sequences of two
consecutive identical words (e.g., "hello hello") and replace them with a single instance
(e.g., "hello").

49
9. Assignment - III

1. Write a Java program to create custom streams using both [Link]() and
[Link](). Demonstrate finite and infinite streams with suitable examples.

2. Explain the concept of Spliterators in Java. Implement a custom Spliterator that divides a list
of numbers into two sub-streams and processes them in parallel.

3. Write a program to demonstrate flatMap() by transforming a stream of lists into a flat stream
of elements. Use a real-world example, such as flattening a list of employees’ names grouped
by department.

4. Implement a text search application using regex in Java. The program should allow the user
to input a text and a regex pattern, and it should display all matching words.

5. Create a Java program that uses regex quantifiers (+, *, ?, {n,m}) to validate different types
of user input such as postal codes, phone numbers, or pin codes.

50
9. Assignment - IV

1. Write a program to demonstrate advanced filtering techniques on streams. For example, filter
numbers greater than 10, divisible by 3, and less than 100, then collect and print the results.

2. Use peek() in a Java stream pipeline to debug the processing of a list of student marks. Show
how the marks are transformed from raw scores to grades step by step.

3. Write a Java program using regex groups and capturing to extract date components (day,
month, year) from a string in the format dd-mm-yyyy.

4. Demonstrate the use of replaceAll() and replaceFirst() in regex for text manipulation. Write a
program to replace all vowels in a sentence with *, but replace only the first digit found in the
string with #.

5. Write a Java program that demonstrates splitting a string using regex. For example, split a CSV
line into fields where values may be separated by commas and optional spaces.

51
10. Part A Questions & Answers
1. What is the primary importance of using streams in Java? CO5, K1
Streams provide a functional programming approach to process sequences of elements in
a declarative manner, allowing for parallel operations, better readability, and concise code.
2. What is a custom stream in Java?. CO5, K1
A custom stream is a user-defined stream where developers create a stream using either
static methods like [Link](), [Link](), or by processing a collection of custom
objects.
3. What does [Link]() do in Java? CO5, K1
[Link]() creates an infinite sequential unordered stream where each element is
generated using the provided Supplier function..
4. What is the use of [Link]() in Java? CO5, K1
[Link]() generates an infinite stream starting from an initial value and applies a given
unary operator repeatedly to produce subsequent elements..
5. What are infinite streams in Java? CO5, K1
Infinite streams are streams that do not have a predefined size and continue to generate
elements either via methods like [Link]() or [Link]() until limited by operations
like limit().
6. What is the role of Spliterator in streams? CO5, K1
A Spliterator is used for splitting the stream into smaller parts for parallel processing and
provides characteristics such as estimated size and ordering for optimization.
7. What is flatMapping in Java Streams? CO5, K1
FlatMapping is the process of transforming each element of a stream into another stream
and then flattening the resulting streams into a single stream using methods like flatMap().
8. How can stream operations be chained in Java? CO5, K1
Stream operations like map(), filter(), and reduce() can be chained by applying multiple
intermediate operations in sequence, resulting in a combined pipeline of operations on the stream
elements.
9. What is stream peeking, and how is peek() used? CO5, K1
Stream peeking is the ability to inspect the elements of a stream during its traversal without
modifying them. The peek() method is used to perform an action on each element as it passes
through the pipeline.
10. Give an example of an advanced filtering technique in streams. CO5, K1
An example of advanced filtering is combining multiple filter() methods to apply complex
conditional logic, such as filter(e -> [Link]("A") && [Link]() > 5).
11. What is a regular expression (regex)? CO5, K2
A regular expression is a sequence of characters that defines a search pattern used for
matching, locating, and manipulating text.
10. Part A Questions & Answers
12. What is the role of character classes in regular expressions? CO5, K2
Character classes define a set of characters to match, such as [a-z] for any
lowercase letter or \d for any digit.

13. What is a quantifier in regular expressions? CO5, K1


Quantifiers specify the number of times a character or group should appear in the pattern,
such as * (zero or more), + (one or more), or {n} (exactly n times).
14. What is pattern matching in regular expressions? CO5, K1
Pattern matching refers to the process of searching a string for a sequence that matches a
defined regex pattern.
15. What are capturing groups in regular expressions? CO5 ,K1
Capturing groups are parts of a regex pattern enclosed in parentheses that allow specific
portions of the matched text to be extracted for further use.
16. What is the [Link] package in Java used for? CO5,K1
The [Link] package provides classes like Pattern and Matcher to support working with
regular expressions for pattern matching and text manipulation.
17. What is the use of the Pattern class in Java? CO5, K1
The Pattern class compiles a regular expression into a pattern that can be used
for pattern matching with strings.

18. What is the Matcher class used for in Java? CO5, K2


The Matcher class is used to match a given input string against a compiled
Pattern object and provides methods to perform operations like finding, replacing, and
extracting matches.

19. How can regex be used for string manipulation in Java? CO5, K2
Regex can be used to manipulate strings by matching patterns for replacing, splitting, or
extracting specific parts of the string using methods like replaceAll() and split().
20. How do you split a string using a regex pattern in Java? CO5, K2
The split() method from the String class or the Pattern class can be used to split a string
into an array based on a regex delimiter.
21. What does replaceAll() do with regex in Java? CO5, K2
The replaceAll() method replaces all occurrences of the regex pattern in the input
string with a given replacement string.

22. What is the use of replaceFirst() in Java? CO5, K2


The replaceFirst() method replaces the first occurrence of a regex pattern in the string with
the given replacement string.

53
10. Part A Questions & Answers
23. What are backreferences in regular expressions? CO5 ,K2
Backreferences refer to previously captured groups in a regex pattern and allow
matching the same text again within the same regex pattern.
24. What is the use of backreferences in the replaceAll() method in Java?
CO5 ,K2
Backreferences can be used in the replacement string of replaceAll() to reuse
parts of the matched pattern in the replacement, for example, replaceAll("(\\w)(\\w)",
"$2$1") swaps adjacent characters.

25. What are backreferences in regular expressions? CO5, K2


matches() attempts to match the entire input string to the pattern, while find()
searches for subsequences that match the pattern within the input string.

54
11. Part B Questions

1. Explain the importance of Advanced Stream Features in Java and discuss how
custom streams are created using [Link]() and [Link](). Provide
an example for each. (K3,CO5)
2. What are Infinite Streams in Java? How are Spliterators used with streams? Explain
their significance with an example. (K3,CO5)
3. Discuss FlatMapping in Java Streams. How does it differ from simple mapping?
Provide a use case where flatMap() is essential. (K3,CO5)
4. What is the peek() method in Java Streams? Discuss its uses and potential pitfalls.
Provide an example of how peek() can be utilized in a stream pipeline. (K3,CO5)
5. Explain the concept of regular expressions (regex) in Java and its key components
(character classes, quantifiers, groups). How does the Pattern and Matcher class
facilitate regex processing in Java? Provide an example of regex pattern matching
and string manipulation using replaceAll(). (K3,CO5)
6. Discuss Advanced Filtering Techniques in Java Streams. How do predicates help in
filtering, and how can multiple conditions be applied? Provide an example
demonstrating multiple filtering criteria using predicates. (K3,CO5)
12. Supportive Online Certifications

1. Java Programming: Complete Beginner to Advanced [Link]


programming-complete-beginner-to- advanced/(Paid)

2. Java DeveloperCertification (Infosys Springboard):


[Link]
0020736264_shared/overview

3. Java Programming Masterclass updated to Java 17: [Link]


the-complete-java-developer-course/ (Paid)

4. Programming in Java: [Link] (Paid)

5. Java Learning Subscription: [Link]


fundamentals/courP_3348 (Paid)

56
13. Real Time Applications

 Desktop GUI Programs

 Mobile Applications

 Artificial intelligence

 Web based Applications

 Big data technology

 Gaming Applications

 Business Applications

 Embedded Systems

 Cloud based Applications

 Scientific Applications

 Distributed Applications

 Web servers and Application servers

 Software Tools

57
14. Contents Beyond the Syllabus
 Reactive Programming with Streams
 Reactive programming is a paradigm centered around asynchronous and non-blocking data streams.
It’s designed for building systems that need to handle high-throughput, real-time data with low
latency, like user interfaces, server-side applications, and reactive systems.
 Java's standard Stream API provides a powerful framework for functional and declarative data
processing, but it is primarily synchronous and pull-based—meaning the data is consumed when
requested. Reactive programming, on the other hand, emphasizes asynchronous, event-driven
streams that are push-based.
 In this context, reactive streams allow you to process data as it arrives, enabling you to handle large
or infinite data streams in a way that is highly efficient and responsive.
What is Reactive Programming?
Reactive programming revolves around:
Asynchronous data flow: Data is processed as it becomes available rather than waiting for the entire
dataset.
Non-blocking execution: The system continues to work even when waiting for data, which allows it to
scale better under high load.
Event-driven systems: Reacting to changes, events, or data emissions in real-time.
The key features of reactive programming include:

Streams of data: Where sequences of events or data are emitted over time.
Backpressure: A mechanism to control the flow of data between producers and consumers, ensuring
consumers are not overwhelmed.
Concurrency and parallelism: Reactive systems efficiently handle multiple operations simultaneously.
Error handling: Errors are considered as part of the data stream and can be handled gracefully without
interrupting the whole system.

Java Reactive Programming Tools:


 Reactor (Project Reactor): A reactive library that is part of the Spring ecosystem. It provides two
main reactive types: Flux (for 0 to N elements) and Mono (for 0 or 1 element).
 RxJava: Another popular reactive library for Java. It provides a more functional approach, focusing
on observables and operators to handle data streams.

 Akka Streams: A toolkit built on top of Akka’s actor system, useful for distributed, reactive systems.
 Vert.x: A toolkit for building reactive applications on the JVM. It is polyglot, supporting Java, Kotlin,
Scala, etc. 58
14. Contents Beyond the Syllabus
The Reactive Streams API in Java (introduced in Java 9) provides the foundation for
building reactive systems. It consists of four main interfaces:

Publisher<T>: Produces elements asynchronously.


Subscriber<T>: Consumes elements from a Publisher.
Subscription: Manages the communication between a Publisher and Subscriber.
Processor<T, R>: A combination of Publisher and Subscriber, representing a processing
step in the stream.

The main goal of Reactive Streams is to handle backpressure, which allows the
subscriber to request only as much data as it can handle from the publisher.
import [Link];

import [Link];
import [Link];

public class ReactiveExample {


public static void main(String[] args) {
Publisher<Integer> publisher = subscriber -> {
[Link](new Subscription() {
@Override

public void request(long n) {


for (int i = 0; i < n; i++) {
[Link](i);
}
[Link]();
}

@Override
public void cancel() {
[Link]("Subscription cancelled");
}
});
};

59
14. Contents Beyond the Syllabus
Subscriber<Integer> subscriber = new Subscriber<>() {
@Override
public void onSubscribe(Subscription subscription) {
[Link](5); // Requesting 5 items from the publisher

@Override
public void onNext(Integer item) {
[Link]("Received: " + item);
}

@Override
public void onError(Throwable t) {
[Link]("Error: " + [Link]());

@Override
public void onComplete() {
[Link]("Done");
}
};

[Link](subscriber);
}
}
In this simple example, a Publisher generates a stream of integers, and a Subscriber requests
and consumes those integers. The subscriber can control how much data it wants to process via
backpressure ([Link](5)).

60
15. Assessment Schedule
Tentative schedule for the Assessment During 2024-2025 Odd Semester

S. Name of the
Assessment Start Date End Date Portion
No.

As Per Academic As Per Academic


1 Unit Test 1 Unit 1
Schedule Schedule

As Per Academic As Per Academic


2 FIAT Unit 1 & 2
Schedule Schedule
As Per Academic As Per Academic
3 Unit Test 2 Unit 3
Schedule Schedule
As Per Academic As Per Academic
4 SIAT Unit 3 & 4
Schedule Schedule
As Per Academic As Per Academic
5 Revision 1 Unit 5, 1 & 2
Schedule Schedule
As Per Academic As Per Academic
6 Revision 2 Unit 3 & 4
Schedule Schedule
As Per Academic As Per Academic
7 Model All 5 Units
Schedule Schedule

61
16. Prescribed Text Books
&
Reference Books
TEXT BOOK:
1. Cay S. Horstmann, "Core Java Volume I--Fundamentals,"
12th Edition, 2019.

2. Joshua Bloch, "Effective Java," 3rd Edition, 2018.


3. Raoul-Gabriel Urma, "Java 8 in Action: Lambdas, Streams,
and Functional-Style Programming," 1st Edition, 2014.
4. Herbert Schildt, "Java: The Complete Reference," 11th
Edition, 2018.
5. Alan Mycroft and Martin Odersky, "Programming in Scala,"
4th Edition, 2020.
REFERENCES:
1. Bruce Eckel, "Thinking in Java," 4th Edition, 2006.
2. Herbert Schildt, "Java: A Beginner's Guide," 8th Edition,
2019.
3. Richard Warburton, "Java 8 Lambdas: Pragmatic Functional
Programming," 1st Edition, 2014.

62
17. Mini Project - Suggestions
1. Log File Analyzer with Streams, Spliterators, and Regex
Develop a Java application that processes large log files. Use Spliterators to split the file into sub-
streams for parallel processing, Streams to filter logs by date range, severity level (INFO, WARN,
ERROR), and keywords, and Regex to extract timestamps and IP addresses. Generate a summary
report with statistics (e.g., total errors, most frequent log messages).

2. Smart Document Cleaner and Formatter


Build a Java program that reads unstructured text files and applies Regex to clean data (remove
extra spaces, validate emails, standardize dates). Use Stream operations (filter, map, peek, flatMap)
to transform the data. Implement a custom Spliterator to handle large files in parallel. Finally, output
the cleaned and formatted text into a new file.

3. Social Media Data Analyzer


Design a Java application that processes social media posts. Use Regex to extract hashtags,
mentions, emails, and URLs. Use Streams (flatMap, filter, chaining, peek) to analyze the frequency of
hashtags and mentions, and apply advanced filtering techniques to remove spam keywords.
Implement Spliterators to process large datasets efficiently and generate a summary dashboard.

4. Student Academic Records Processor


Create a Java system that manages student academic records from CSV files. Use Streams (flatMap)
to flatten nested data like marks by subject, apply advanced filtering to identify students meeting
criteria (e.g., GPA > 8), and use Regex to validate roll numbers, email IDs, and phone numbers.
Implement a Spliterator to process large student datasets in parallel and generate analytical reports.

5. Real-Time Data Monitoring and Cleaning System


Implement a Java application that simulates infinite data streams (e.g., sensor readings) using
[Link]() and [Link](). Apply Streams to filter abnormal readings, use peek() to log
processing steps, and apply Regex to validate and clean incoming string data (e.g., date-time
formats, IDs). Use a custom Spliterator for splitting continuous data streams for parallel analysis and
produce alerts/reports.

87
Thank you

Disclaimer:

This document is confidential and intended solely for the educational purpose of
RMK Group of Educational Institutions. If you have received this document through
email in error, please notify the system manager. This document contains
proprietary information and is intended only to the respective group / learning
community as intended. If you are not the addressee you should not disseminate,
distribute, or copy through e-mail. Please notify the sender immediately by e-mail if you
have received this document by mistake and delete this document from your system.
If you are not the intended recipient you are notified that disclosing, copying,
distributing, or taking any action in reliance on the contents of this information is strictly
prohibited.

90

You might also like