☕ JAVA PROGRAMMING
Advanced Java — Complete Study Notes
Modules Covered
Module 1 → Nested Classes (Static, Inner, Local, Anonymous)
Module 2 → Functional Interfaces & Lambda Expressions
Module 3 → Utility Classes – Working with Dates ([Link])
Module 4 → Exceptions & Assertions
Module 5 → Collections Framework (Generics, ArrayList, TreeSet, HashMap, Deque)
Detailed Notes • 18-Day Study Plan • Viva Q&A (Easy→Hard) • Coding Problems
📅 18-Day Study Plan
1.5–2 hrs/day. Read → understand → write code → run. Never skip the coding step!
Day Topic Tasks Revise
Day Static & Inner Code both; access outer fields; observe —
1 Nested Class difference
Day Local & Anonymous Write anonymous Comparator; local Day 1
2 Class class inside method
Day Functional Interface Create own @FunctionalInterface; use Day 2
3 with lambda
Day Lambda Basics Rewrite anonymous classes as lambdas Day 3
4 (5 examples)
Day Lambda – forEach, sort, filter with lambdas Day 4
5 Collections &
Streams
Day [Link] – Create, manipulate, format dates (5 Day 5
6 LocalDate/Time programs)
Day [Link] – Calculate age, time difference, timezone Day 6
7 Period/Duration/ZDT
Day Exception Hierarchy Draw hierarchy; identify checked vs Day 7
8 unchecked
Day try-catch-finally Write programs for each exception type; Day 8
9 trace finally
Day throw, throws, Propagate exception across 3 methods; Day 9
10 propagation use throws
Day Multi-catch & try- AutoCloseable class; multi-catch block Day 10
11 with-resources
Day Custom Exceptions Checked + unchecked custom Day 11
12 exceptions
Day Assertions Enable with -ea flag; write invariant tests Day 12
13
Day Generics & ArrayList Generic class/method; ArrayList CRUD + Day 13
14 sort
Day TreeSet + Natural order vs custom order Day 14
15 Comparable/Compar
ator
Day HashMap CRUD; iterate entrySet; Day 15
16 computeIfAbsent; word count
Day Deque Stack/Queue operations using Day 16
17 ArrayDeque
Day Full Revision + Mock Attempt all viva Qs; 2 coding Qs/module All
18 Viva
📘 Module 1: Nested Classes
1.1 Overview of Nested Classes
A nested class is a class defined inside another class. Java has four types:
Type static? Access to Outer? Typical Use
Static Nested Class Yes (static) Only static members of outer Helper class; builder
pattern
Non-static Inner Class No All members (incl. private) Event listeners;
iterators
Local Class No Effectively final locals Algorithm-scoped
helper
Anonymous Class No Effectively final locals One-shot interface
implementation
1.2 Static Nested Class
Declared with static keyword inside a class. Does NOT need an outer class instance. Can only access
static members of the outer class.
class Outer {
static int outerStatic = 100;
int outerInstance = 200; // NOT accessible in static nested class
static class StaticNested {
void display() {
[Link]("outerStatic = " + outerStatic); // OK
// [Link](outerInstance); // ERROR
}
}
}
// Creating a static nested class object — no outer instance needed
[Link] obj = new [Link]();
[Link]();
Static nested class is essentially a top-level class that happens to be inside another class
for namespace/packaging purposes.
1.3 Non-static Inner Class
No static keyword. Implicitly holds a reference to its outer class instance. Can access ALL outer class
members including private ones.
class Outer {
private String msg = "Hello from Outer";
class Inner {
void show() {
[Link](msg); // directly accesses outer private field
}
}
}
// MUST create outer object first
Outer outer = new Outer();
[Link] inner = [Link] Inner(); // syntax: [Link] Inner()
[Link]();
Inner class creates a hidden reference to outer class. This means the outer object cannot be
GC'd as long as the inner object exists — be careful with memory!
1.4 Static vs Non-static Nested Class
Feature Static Nested Non-static Inner
Outer instance needed? No Yes — [Link] Inner()
Access outer static members? Yes Yes
Access outer instance members? No Yes (all, including private)
Can have static members? Yes No (only static final constants)
Memory No hidden outer ref Holds hidden ref to outer
1.5 Local Class
Defined inside a method, constructor, or block. Visible only within that scope. Can access effectively-
final local variables from the enclosing method.
class Processor {
void process(String data) {
final int VERSION = 2;
class Formatter { // local class — inside method
String format() {
return "[v" + VERSION + "] " + data; // data must be effectively
final
}
}
Formatter f = new Formatter();
[Link]([Link]());
}
}
1.6 Anonymous Class
A class without a name, defined and instantiated in one expression. Used for one-time implementation
of an interface or abstract class.
// Without anonymous class — verbose
interface Greeter { void greet(String name); }
class HelloGreeter implements Greeter {
public void greet(String name) { [Link]("Hello " + name); }
}
Greeter g = new HelloGreeter();
// With anonymous class — inline, compact
Greeter g = new Greeter() {
@Override
public void greet(String name) {
[Link]("Hello " + name);
}
};
[Link]("Shivam");
// Anonymous class with Comparator (classic sorting)
List<String> names = [Link]("Charlie", "Alice", "Bob");
[Link](names, new Comparator<String>() {
@Override
public int compare(String a, String b) { return [Link](b); }
});
1.7 Viva Questions – Module 1
[Easy] What is a nested class?
Ans: A class defined inside another class. Java has 4 types: static nested, inner (non-static), local, and
anonymous.
[Easy] What is the difference between static and non-static nested class?
Ans: Static nested: accessed without outer instance; can only access outer static members. Inner class:
requires outer instance; can access all outer members including private.
[Easy] What is an anonymous class?
Ans: A nameless class defined and instantiated in a single expression. Used for one-time implementations
of interfaces or abstract classes.
[Medium] Why does a non-static inner class hold a reference to the outer class?
Ans: Because it may need to access instance members of the outer class. The JVM achieves this by
storing a hidden reference to the outer object.
[Medium] What are effectively final variables?
Ans: Local variables that are not declared final but whose values never change after initialization. They
can be used by local and anonymous classes from Java 8+.
[Medium] Can a static nested class access instance variables of the outer class?
Ans: No. Without an outer instance reference, it can only access static members of the outer class.
[Hard] What is the syntax to instantiate a non-static inner class?
Ans: Outer outer = new Outer(); [Link] inner = [Link] Inner();
[Hard] What are the memory implications of using inner classes?
Ans: Inner class holds a hidden reference to the outer class instance, preventing GC of the outer object.
This can cause memory leaks if the inner object lives longer than expected.
1.8 Coding Questions – Module 1
Q1. Create an outer class LinkedList with a private static nested class Node (data, next). Build a
simple chain of 3 nodes.
Hint: Node is a static nested class; accessed as [Link]
Q2. Create a BankAccount outer class with inner class Transaction. Transaction accesses private
balance of BankAccount.
Hint: Inner class reads [Link] directly
Q3. Sort a list of Employee objects by salary using an anonymous Comparator class.
Hint: new Comparator<Employee>() { compare by [Link] - [Link] }
Q4. Write a local class Validator inside a method that checks if a String matches an email pattern.
Hint: Local class with boolean isValid(String s) method
📗 Module 2: Functional Interfaces & Lambda
Expressions
2.1 Functional Interface
An interface with exactly ONE abstract method. It may have any number of default or static methods.
Annotated with @FunctionalInterface (optional but recommended).
@FunctionalInterface
interface Calculator {
int operate(int a, int b); // exactly ONE abstract method
default void printInfo() { // default methods allowed
[Link]("Calculator FI");
}
}
@FunctionalInterface causes a compile error if the interface has 0 or 2+ abstract methods —
acts as a safety guard.
2.2 Built-in Functional Interfaces ([Link])
Interface Abstract Method Use Case Example
Predicate<T> boolean test(T t) Test/filter condition x -> x > 10
Function<T,R> R apply(T t) Transform T to R s -> [Link]()
Consumer<T> void accept(T t) Consume/use a value s -> sout(s)
Supplier<T> T get() Provide/supply a value () -> new
ArrayList<>()
BiFunction<T,U,R> R apply(T t, U u) Two inputs, one output (a,b) -> a+b
UnaryOperator<T> T apply(T t) Same type in and out x -> x * 2
BinaryOperator<T> T apply(T t1, T t2) Two same-type inputs (a,b) -> a+b
Runnable void run() No input, no output () -> doWork()
2.3 Lambda Expression Syntax
// Full syntax
(parameters) -> { body }
// Rules for shorthand:
// 1. Single parameter — omit parentheses
x -> x * 2
// 2. Single expression body — omit braces and return
(a, b) -> a + b
// 3. No parameters — empty parentheses required
() -> [Link]("Hello")
// 4. Multi-statement body — must have braces and return
(a, b) -> {
int sum = a + b;
return sum * 2;
}
2.4 Lambda Replacing Anonymous Class
// Anonymous class (old way)
Runnable r1 = new Runnable() {
public void run() { [Link]("Running!"); }
};
// Lambda (new way — same thing, 1 line)
Runnable r2 = () -> [Link]("Running!");
// Comparator anonymous → lambda
// Before:
[Link](list, new Comparator<String>() {
public int compare(String a, String b) { return [Link](b); }
});
// After:
[Link](list, (a, b) -> [Link](b));
// Or even shorter with method reference:
[Link](String::compareTo);
2.5 Lambda with Built-in Functional Interfaces
import [Link].*;
// Predicate — test a condition
Predicate<Integer> isEven = n -> n % 2 == 0;
[Link]([Link](4)); // true
// Function — transform
Function<String, Integer> strLen = s -> [Link]();
[Link]([Link]("Hello")); // 5
// Consumer — use/print
Consumer<String> printer = s -> [Link](">> " + s);
[Link]("Java"); // >> Java
// Supplier — provide
Supplier<Double> random = () -> [Link]();
[Link]([Link]());
// BinaryOperator — two same-type operands
BinaryOperator<Integer> add = (a, b) -> a + b;
[Link]([Link](3, 4)); // 7
2.6 Method References
Shorthand for lambda when it just calls an existing method. Four types:
Type Syntax Lambda Equivalent
Static method ClassName::staticMethod x -> [Link](x)
Instance method (specific) obj::instanceMethod x -> [Link](x)
Instance method (arbitrary) ClassName::instanceMethod (obj,x) -> [Link](x)
Constructor ClassName::new x -> new ClassName(x)
List<String> names = [Link]("Alice","Bob","Charlie");
// Static method ref
[Link]([Link]::println); // same as s -> [Link](s)
// Instance method ref (arbitrary)
[Link](String::compareToIgnoreCase);
// Constructor ref
Supplier<ArrayList<String>> listMaker = ArrayList::new;
2.7 Lambda with Collections (forEach, removeIf)
List<Integer> nums = new ArrayList<>([Link](1,2,3,4,5,6,7,8));
// forEach with lambda
[Link](n -> [Link](n + " ")); // 1 2 3 4 5 6 7 8
// removeIf with Predicate lambda
[Link](n -> n % 2 == 0);
[Link](nums); // [1, 3, 5, 7]
// sort with Comparator lambda
List<String> words = [Link]("banana","apple","cherry");
[Link]((a, b) -> [Link]() - [Link]()); // by length
[Link](words); // [apple, banana, cherry]
2.8 Viva Questions – Module 2
[Easy] What is a functional interface?
Ans: An interface with exactly one abstract method. Can have default and static methods. Annotated with
@FunctionalInterface.
[Easy] What is a lambda expression?
Ans: A concise way to represent an anonymous function (implementation of a functional interface) — no
name, no return type declaration.
[Easy] What does @FunctionalInterface annotation do?
Ans: It instructs the compiler to verify that the interface has exactly one abstract method. If not, it causes a
compile error.
[Medium] Name four built-in functional interfaces and their abstract methods.
Ans: Predicate: test(T). Function: apply(T). Consumer: accept(T). Supplier: get(). All in [Link]
package.
[Medium] What is a method reference?
Ans: A shorthand lambda that directly refers to an existing method: ClassName::method or
object::method. Makes code cleaner.
[Medium] Can lambda expressions access local variables?
Ans: Yes, but only if they are effectively final (not modified after initialization). Captured variables are
copied for the lambda.
[Medium] What is the difference between Predicate and Function?
Ans: Predicate: takes T, returns boolean — for testing/filtering. Function: takes T, returns R (different type)
— for transforming.
[Hard] Why can lambda replace anonymous classes for functional interfaces but not all interfaces?
Ans: Lambda works only for functional interfaces (1 abstract method). Multi-method interfaces still require
anonymous class or concrete implementation.
2.9 Coding Questions – Module 2
Q1. Write a Predicate lambda to filter names longer than 5 chars from a list. Print results.
Hint: [Link]().filter(s->[Link]()>5).forEach(sout) OR removeIf on copy
Q2. Create a custom @FunctionalInterface StringTransformer with apply(String). Use it with 3
different lambdas: uppercase, reverse, trim.
Hint: Assign different lambdas: st = s -> [Link]()
Q3. Use Function<String, Integer> to map a list of strings to their lengths.
Hint: [Link]().map(String::length).collect([Link]())
Q4. Sort a list of students by GPA descending using a Comparator lambda.
Hint: [Link]((s1,s2) -> [Link]([Link], [Link]))
Q5. Demonstrate all 4 types of method references with examples.
Hint: Static, instance specific, instance arbitrary, constructor
📙 Module 3: Utility Classes – Working with Dates
3.1 Why [Link]? (Java 8+)
The old [Link] and Calendar were mutable, poorly designed, and not thread-safe. Java 8
introduced [Link] (inspired by Joda-Time) — immutable, fluent, and comprehensive.
Old (Avoid) New (Use This) Description
[Link] [Link] Date without time
[Link] [Link] Time without date
[Link] [Link] Date + time, no timezone
[Link] [Link] Date + time + timezone
SimpleDateFormat [Link] Thread-safe formatter
ormatter
— [Link] Duration in years/months/days
— [Link] Duration in
hours/minutes/seconds/nanos
— [Link] Machine timestamp (epoch-based)
3.2 LocalDate
import [Link];
import [Link];
LocalDate today = [Link]();
LocalDate birthday = [Link](2000, [Link], 15);
LocalDate parsed = [Link]("2024-12-25");
// Manipulation (returns NEW object — immutable)
LocalDate nextWeek = [Link](7);
LocalDate lastMonth = [Link](1);
LocalDate nextYear = [Link](1);
// Queries
[Link]([Link]()); // MONDAY
[Link]([Link]()); // e.g. 15
[Link]([Link]()); // e.g. 6
[Link]([Link]()); // true/false
[Link]([Link](nextWeek)); // true
3.3 LocalTime
import [Link];
LocalTime now = [Link]();
LocalTime alarm = [Link](6, 30, 0); // 06:30:00
LocalTime parsed = [Link]("14:30:00");
LocalTime later = [Link](2).plusMinutes(15); // 08:45
[Link]([Link]()); // e.g. 14
[Link]([Link]()); // e.g. 30
[Link]([Link](now)); // true/false
3.4 LocalDateTime
import [Link];
LocalDateTime now = [Link]();
LocalDateTime meeting = [Link](2025, 6, 15, 10, 30);
// Combine LocalDate + LocalTime
LocalDate d = [Link](2025, 1, 1);
LocalTime t = [Link](9, 0);
LocalDateTime dt = [Link](d, t);
// Extract parts
[Link]([Link]()); // 2025-01-01
[Link]([Link]()); // 09:00
3.5 ZonedDateTime
import [Link];
import [Link];
ZonedDateTime indiaTime = [Link]([Link]("Asia/Kolkata"));
ZonedDateTime utcTime = [Link]([Link]("UTC"));
ZonedDateTime nyTime = [Link]([Link]("America/New_York"));
// Convert between zones
ZonedDateTime londonTime = [Link]([Link]("Europe/London"));
// List available zone IDs
[Link]().stream().sorted().forEach([Link]::println);
3.6 Period (date-based) vs Duration (time-based)
Class Measures Units Example
Period Date-based gap Years, Months, Days Age calculation
Duration Time-based gap Hours, Minutes, Elapsed time
Seconds, Nanos
// Period — calculate age
LocalDate birthDate = [Link](2000, 6, 15);
LocalDate today = [Link]();
Period age = [Link](birthDate, today);
[Link]([Link]() + " years, " + [Link]() + " months");
// Duration — elapsed time
LocalDateTime start = [Link](2025, 1, 1, 8, 0);
LocalDateTime end = [Link](2025, 1, 1, 10, 30);
Duration elapsed = [Link](start, end);
[Link]([Link]() + " hrs " + [Link]() + " mins");
3.7 DateTimeFormatter
import [Link];
LocalDate today = [Link]();
// Predefined formatters
[Link]([Link](DateTimeFormatter.ISO_LOCAL_DATE)); // 2025-06-15
// Custom pattern
DateTimeFormatter fmt = [Link]("dd-MM-yyyy");
[Link]([Link](fmt)); // 15-06-2025
// Parse a custom-formatted string
LocalDate parsed = [Link]("15-06-2025", fmt);
[Link](parsed); // 2025-06-15
Pattern Symbol Meaning Example
yyyy 4-digit year 2025
MM 2-digit month 06
MMM 3-letter month Jun
dd 2-digit day 15
HH Hour (24h) 14
mm Minute 30
ss Second 45
E Day of week (short) Mon
EEEE Day of week (full) Monday
3.8 Viva Questions – Module 3
[Easy] Why was [Link] introduced in Java 8?
Ans: [Link] and Calendar were mutable, not thread-safe, poorly designed. [Link] is immutable,
thread-safe, and has a fluent API.
[Easy] What is the difference between LocalDate and LocalDateTime?
Ans: LocalDate: date only (year-month-day). LocalDateTime: date + time but no timezone info.
[Medium] What is the difference between Period and Duration?
Ans: Period measures date-based gaps (years, months, days). Duration measures time-based gaps
(hours, minutes, seconds, nanoseconds).
[Medium] Why are [Link] classes immutable?
Ans: Immutability ensures thread safety (can be shared without synchronization) and prevents accidental
modification.
[Medium] How do you format and parse dates in Java 8+?
Ans: Use DateTimeFormatter. Format: [Link](formatter). Parse: [Link](string, formatter).
[Medium] What is ZonedDateTime?
Ans: A date-time with timezone info. Used when timezone context matters (e.g., scheduling meetings
across timezones).
[Hard] What does [Link]().plusDays(7) return?
Ans: A NEW LocalDate object representing 7 days from today. The original is unchanged (immutability).
3.9 Coding Questions – Module 3
Q1. Calculate a person's exact age in years, months, and days using LocalDate and Period.
Hint: [Link](birthDate, [Link]())
Q2. Write a program to display the current date in 'dd-MMMM-yyyy, EEEE' format (e.g. 15-June-2025,
Sunday).
Hint: [Link]("dd-MMMM-yyyy, EEEE")
Q3. Find how many days are left until the next New Year's Day.
Hint: [Link](today, [Link]([Link]()+1, 1, 1))
Q4. Show the current time in IST, UTC, and EST simultaneously using ZonedDateTime.
Hint: [Link]([Link]("Asia/Kolkata")), etc.
Q5. Calculate the duration between two LocalDateTimes and display hours and minutes.
Hint: [Link](start, end).toHours() and toMinutesPart()
📒 Module 4: Exceptions and Assertions
4.1 What is an Exception?
An exception is an event that disrupts the normal flow of program execution. Java provides a robust
exception handling mechanism to handle runtime errors gracefully.
Term Meaning
Exception Abnormal event during program execution
Exception Handling Mechanism to handle exceptions without program crash
throw Manually throw an exception object
throws Declares which checked exceptions a method may throw
try Block of code monitored for exceptions
catch Block that handles a specific exception
finally Block that always executes (cleanup code)
4.2 Exception Class Hierarchy
Throwable (root)
Throwable
/ \
Error Exception
/ \ / \
OutOf Stack IOException RuntimeException
Memory Overflow | / \
Error FileNF NullPointer ArrayIndex
Found Exception OutOfBounds
Type Checked? Examples Must Handle?
Error Unchecked OutOfMemoryError, No (JVM problems —
StackOverflowError unrecoverable)
Checked Exception Yes IOException, Yes — must catch or declare
FileNotFoundException, throws
SQLException
Unchecked (Runtime) No NullPointerException, No — optional handling
ArrayIndexOutOfBoundsExceptio
n
Checked exceptions: compiler forces you to handle them. Unchecked (RuntimeException):
optional — represent programming errors.
4.3 try-catch-finally
try {
// code that might throw an exception
int result = 10 / 0; // ArithmeticException
} catch (ArithmeticException e) {
[Link]("Caught: " + [Link]()); // / by zero
} finally {
[Link]("Finally always runs!"); // always executes
}
Scenario finally executes?
try completes normally Yes
catch handles exception Yes
return inside try Yes (before return)
[Link]() called No
Power failure / JVM crash No
finally is used for cleanup: closing files, releasing connections, freeing resources —
regardless of exception.
4.4 Multiple catch Blocks
try {
String s = null;
int[] arr = new int[5];
[Link]([Link]()); // NullPointerException
[Link](arr[10]); // ArrayIndexOutOfBoundsException
} catch (NullPointerException e) {
[Link]("Null: " + [Link]());
} catch (ArrayIndexOutOfBoundsException e) {
[Link]("Array: " + [Link]());
} catch (Exception e) {
[Link]("General: " + [Link]()); // catches rest
}
More specific exceptions must come BEFORE more general ones. Putting Exception first
causes compile error for subsequent catches.
4.5 Multi-catch Block (Java 7+)
Handle multiple exception types in a single catch block when the handling code is the same.
try {
riskyOperation();
} catch (IOException | SQLException | ParseException e) {
[Link]("Data error: " + [Link]());
[Link](e);
}
Multi-catch parameter (e) is implicitly final — you cannot reassign it inside the block.
4.6 throw and throws
// throw — manually throw an exception
void validateAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative: " + age);
}
}
// throws — declare checked exceptions in method signature
void readFile(String path) throws IOException, FileNotFoundException {
FileReader fr = new FileReader(path); // checked exception
// ...
}
throw throws
Used inside a method body Used in method signature
Throws actual exception object Declares exception types that may be thrown
Followed by exception instance Followed by exception class name(s)
Can throw only one at a time Can declare multiple (comma-separated)
4.7 Exception Propagation
When a method doesn't handle an exception, it propagates (bubbles up) to the caller. If uncaught all
the way to main(), the program terminates.
void methodC() { int x = 10/0; } // throws ArithmeticException
void methodB() { methodC(); } // propagates up
void methodA() { methodB(); } // propagates up
void main() {
try {
methodA(); // caught here
} catch (ArithmeticException e) {
[Link]("Caught in main!");
}
}
4.8 try-with-resources (Java 7+)
Automatically closes resources (that implement AutoCloseable) when try block exits — no need for
finally to close.
// Old way — verbose and error-prone
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("[Link]"));
[Link]([Link]());
} catch (IOException e) { [Link](); }
} finally {
if (br != null) try { [Link](); } catch (IOException e) { }
}
// New way — auto-close guaranteed
try (BufferedReader br = new BufferedReader(new FileReader("[Link]"))) {
[Link]([Link]());
} catch (IOException e) {
[Link]();
}
// [Link]() called automatically!
// Custom AutoCloseable resource
class DBConnection implements AutoCloseable {
DBConnection() { [Link]("Connection opened"); }
@Override
public void close() { [Link]("Connection closed"); }
}
try (DBConnection conn = new DBConnection()) {
[Link]("Querying DB...");
} // close() called automatically
Multiple resources in try-with-resources: closed in REVERSE order of declaration. Resource
declared last is closed first.
4.9 Custom Exceptions
// Custom checked exception
class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) {
super("Insufficient funds. Short by: Rs." + amount);
[Link] = amount;
}
public double getAmount() { return amount; }
}
// Custom unchecked exception
class InvalidAgeException extends RuntimeException {
public InvalidAgeException(String msg) { super(msg); }
}
// Using custom exception
class BankAccount {
double balance = 1000;
void withdraw(double amt) throws InsufficientFundsException {
if (amt > balance)
throw new InsufficientFundsException(amt - balance);
balance -= amt;
}
}
4.10 Assertions
Assertions are statements that test a boolean assumption at runtime. Used for debugging/testing, NOT
for production validation.
// Syntax 1: basic
assert condition;
// Syntax 2: with message
assert condition : "Error message if false";
// Example
int speed = calculateSpeed();
assert speed > 0 : "Speed must be positive but was: " + speed;
// Enable assertions at runtime: java -ea MyClass
// Disable (default): java -da MyClass
Assertions are DISABLED by default. Enable with -ea (enableassertions) JVM flag. Never
use assertions for input validation in production — use if-throw instead.
Assertion if-throw
For internal invariants (programming For input validation from users/external systems
errors)
Disabled in production Always active
AssertionError if fails Any exception of choice
java -ea flag needed Always runs
4.11 Viva Questions – Module 4
[Easy] What is an exception?
Ans: An abnormal event that disrupts normal program flow. Java represents exceptions as objects of
classes that extend Throwable.
[Easy] What is the difference between checked and unchecked exceptions?
Ans: Checked: compiler forces handling (try-catch or throws). Unchecked (RuntimeException): optional
handling, represent programming bugs.
[Easy] What does the finally block do?
Ans: Executes always — whether exception is thrown or not, whether caught or not. Exception:
[Link]() or JVM crash.
[Medium] What is the difference between throw and throws?
Ans: throw: used in method body to actually throw an exception object. throws: used in method signature
to declare checked exceptions the method may propagate.
[Medium] What is try-with-resources?
Ans: Java 7 feature. Resources implementing AutoCloseable are auto-closed when the try block exits,
eliminating manual finally cleanup.
[Medium] What is exception propagation?
Ans: When a method doesn't handle an exception, it passes it up the call stack to the caller. This
continues until caught or main() is reached, causing program termination.
[Medium] What is multi-catch? Any restrictions?
Ans: Catching multiple exception types in one catch block: catch(A | B | C e). Restriction: the exceptions
must not be in parent-child relationship. Parameter e is implicitly final.
[Hard] Can finally block have a return statement?
Ans: Yes, but it overrides any return in try or catch. Highly discouraged — causes unexpected behaviour
by swallowing exceptions.
[Hard] What is the difference between Error and Exception?
Ans: Error: JVM-level problems (OutOfMemoryError, StackOverflowError) — unrecoverable, not for
application code. Exception: recoverable conditions — application code should handle.
[Hard] What are assertions and when should you NOT use them?
Ans: Boolean checks for internal invariants. Should NOT be used for: input validation (disabled by
default), argument checking for public methods, side-effects inside assert.
4.12 Coding Questions – Module 4
Q1. Write a program demonstrating try-catch-finally with division by zero and print the order of
execution.
Hint: Show all 3 blocks executing; what happens with return inside try?
Q2. Create a custom checked exception InsufficientFundsException. Write a BankAccount with
withdraw() that throws it.
Hint: extends Exception; throw in withdraw(); catch in main
Q3. Create a custom AutoCloseable class DatabaseConnection. Use try-with-resources. Verify close()
is called.
Hint: implements AutoCloseable { public void close() { sout("closed") } }
Q4. Demonstrate exception propagation: 3 methods chained (A calls B calls C). C throws, catch only
in A.
Hint: No try-catch in B and C — observe propagation
Q5. Write a multi-catch block that handles NumberFormatException,
ArrayIndexOutOfBoundsException together.
Hint: catch (NumberFormatException | ArrayIndexOutOfBoundsException e)
Q6. Write a method with assertion that validates a square root input is non-negative.
Hint: assert value >= 0 : "Input must be >= 0"; run with -ea
📕 Module 5: Collections Framework
5.1 Collections Framework Overview
The Java Collections Framework provides a unified architecture for storing and manipulating groups of
objects. All collections are in [Link].
Interface Common Implementation Ordered? Duplicates? Null?
List ArrayList, LinkedList Yes (index) Yes Yes
Set HashSet, TreeSet, No/Yes No One null (not
LinkedHashSet TreeSet)
Queue LinkedList, PriorityQueue, Yes Yes No (PQ)
ArrayDeque (FIFO/priority)
Deque ArrayDeque, LinkedList Both ends Yes Yes
(ArrayDeque)
Map HashMap, TreeMap, No/Yes Keys no, 1 null key
LinkedHashMap Values yes (HashMap)
5.2 Generics
Generics enable type safety at compile time — no need for casting, eliminates ClassCastException at
runtime.
// Without generics (raw type — avoid)
List list = new ArrayList();
[Link]("Hello"); [Link](123); // any type — no safety
String s = (String) [Link](1); // ClassCastException at runtime!
// With generics (type-safe)
List<String> list = new ArrayList<>();
[Link]("Hello");
// [Link](123); // COMPILE ERROR — type enforced
String s = [Link](0); // no cast needed
Generic Class
class Pair<T, U> {
T first; U second;
Pair(T f, U s) { first = f; second = s; }
@Override
public String toString() { return "(" + first + ", " + second + ")"; }
}
Pair<String, Integer> p = new Pair<>("Age", 25);
[Link](p); // (Age, 25)
Generic Method
public static <T extends Comparable<T>> T max(T a, T b) {
return [Link](b) >= 0 ? a : b;
}
[Link](max(10, 20)); // 20
[Link](max("apple", "banana")); // banana
Bounded Type Parameters
// Upper bound — T must be Number or subclass
<T extends Number> double sum(List<T> list) { ... }
// Wildcard — unknown type
void printList(List<?> list) { [Link]([Link]::println); }
5.3 ArrayList
Resizable array implementation of List. O(1) random access, O(n) insert/delete at middle. Not thread-
safe.
import [Link].*;
List<String> fruits = new ArrayList<>();
// Add
[Link]("Apple");
[Link]("Banana");
[Link](0, "Mango"); // insert at index 0
// Access
[Link]([Link](1)); // Apple
[Link]([Link]()); // 3
[Link]([Link]("Banana")); // true
[Link]([Link]("Banana")); // 2
// Update & Remove
[Link](0, "Papaya"); // replace index 0
[Link]("Banana"); // by value
[Link](0); // by index
// Iterate
for (String f : fruits) { [Link](f); }
[Link]([Link]::println); // lambda
// Sort
[Link](fruits); // natural order
[Link]((a, b) -> [Link](a)); // reverse order lambda
[Link](fruits, [Link]()); // reverse
// Search, subList, clear
int idx = [Link](fruits, "Mango"); // sort first!
List<String> sub = [Link](0, 2);
[Link]();
5.4 TreeSet — Comparable & Comparator
TreeSet stores elements in sorted order (Red-Black Tree). O(log n) for add, remove, contains. No
duplicates. No null.
Natural Ordering — Comparable
class Student implements Comparable<Student> {
String name; int marks;
Student(String n, int m) { name=n; marks=m; }
@Override
public int compareTo(Student other) {
return [Link]([Link], [Link]); // ascending by marks
}
@Override
public String toString() { return name + "(" + marks + ")"; }
}
TreeSet<Student> set = new TreeSet<>();
[Link](new Student("Alice", 85));
[Link](new Student("Bob", 72));
[Link](new Student("Charlie", 95));
[Link](set); // [Bob(72), Alice(85), Charlie(95)]
Custom Ordering — Comparator (doesn't modify class)
// Sort by name alphabetically
Comparator<Student> byName = (s1, s2) -> [Link]([Link]);
TreeSet<Student> byNameSet = new TreeSet<>(byName);
[Link](set);
[Link](byNameSet); // [Alice(85), Bob(72), Charlie(95)]
Feature Comparable Comparator
Interface [Link] [Link]
Method compareTo(T o) — 1 compare(T o1, T o2) — 1 method
method
Implementation Inside the class itself Separate class or lambda
Modifies class? Yes No
Sort order Single natural order Multiple custom orders
Used with TreeSet, TreeSet(comparator), sort(list, comp)
[Link]()
5.5 HashMap
Stores key-value pairs. O(1) average for get/put/remove. Keys must be unique. One null key allowed.
Not ordered. Not thread-safe.
import [Link].*;
Map<String, Integer> scores = new HashMap<>();
// Put, get, update
[Link]("Alice", 90);
[Link]("Bob", 75);
[Link]("Charlie", 85);
[Link]("Alice", 95); // updates Alice's score (keys unique)
[Link]([Link]("Bob")); // 75
[Link]([Link]("Dan", 0)); // 0 (key absent)
[Link]([Link]("Alice")); // true
[Link]([Link](75)); // true
// Iterate — 3 ways
// 1. entrySet (best — both key and value)
for ([Link]<String, Integer> e : [Link]()) {
[Link]([Link]() + " → " + [Link]());
}
// 2. keySet
for (String key : [Link]()) { [Link](key); }
// 3. forEach with lambda
[Link]((k, v) -> [Link](k + " : " + v));
// Useful operations
[Link]("Bob");
[Link]("Dave", 80); // add only if key doesn't exist
[Link]("Eve", k -> [Link]() * 10);
[Link]("Alice", 5, Integer::sum); // Alice: 95 + 5 = 100
Word Frequency Counter — Classic HashMap Pattern
String text = "apple banana apple cherry banana apple";
Map<String, Integer> freq = new HashMap<>();
for (String word : [Link](" ")) {
[Link](word, [Link](word, 0) + 1);
}
[Link](freq); // {apple=3, banana=2, cherry=1}
5.6 Deque
Double-Ended Queue — elements can be added/removed from BOTH ends. Implements both Stack
and Queue behaviour. ArrayDeque is the preferred implementation.
Operation Deque Method Deque Method Queue Role Stack Role
(throws ex) (returns null/false)
Add to front addFirst(e) offerFirst(e) — push(e)
Add to back addLast(e) offerLast(e) offer(e) / add(e) —
Remove front removeFirst() pollFirst() poll() / remove() pop()
Remove back removeLast() pollLast() — —
Peek front getFirst() peekFirst() peek() peek()
Peek back getLast() peekLast() — —
import [Link];
import [Link];
// Using Deque as a Queue (FIFO)
Deque<String> queue = new ArrayDeque<>();
[Link]("Task1");
[Link]("Task2");
[Link]("Task3");
[Link]([Link]()); // Task1 (FIFO)
[Link]([Link]()); // Task2 (not removed)
// Using Deque as a Stack (LIFO)
Deque<Integer> stack = new ArrayDeque<>();
[Link](10);
[Link](20);
[Link](30);
[Link]([Link]()); // 30 (LIFO)
[Link]([Link]()); // 20 (not removed)
// Using both ends — Sliding window, palindrome check
Deque<Character> dq = new ArrayDeque<>();
for (char c : "racecar".toCharArray()) [Link](c);
boolean isPalin = true;
while ([Link]() > 1) {
if ([Link]() != [Link]()) { isPalin = false; break; }
}
[Link]("Palindrome: " + isPalin); // true
5.7 Viva Questions – Module 5
[Easy] What is the Collections Framework?
Ans: A unified architecture of interfaces and classes for storing and manipulating groups of objects. Core
interfaces: List, Set, Queue, Map.
[Easy] What are Generics in Java?
Ans: A feature that allows type parameters in classes/methods, enabling compile-time type safety and
eliminating the need for casting.
[Medium] Difference between ArrayList and LinkedList?
Ans: ArrayList: dynamic array, O(1) access, O(n) insert/delete middle. LinkedList: doubly linked list, O(n)
access, O(1) insert/delete at known position. ArrayList preferred for most uses.
[Medium] What is the difference between Comparable and Comparator?
Ans: Comparable: implemented inside the class (compareTo); defines natural order. Comparator: external
class or lambda (compare); defines custom/multiple orderings.
[Hard] How does HashMap work internally?
Ans: Uses an array of buckets + linked lists/trees. hashCode() determines bucket; equals() resolves
collisions. Java 8+: bucket converts to tree when > 8 elements.
[Medium] What is TreeSet and how does it order elements?
Ans: A Set implemented as a Red-Black Tree. Elements are stored in sorted order using their natural
ordering (Comparable) or a provided Comparator.
[Medium] What is a Deque? How can it simulate Stack and Queue?
Ans: Deque = Double-Ended Queue. As Stack: push/pop from front. As Queue: offer to back, poll from
front. ArrayDeque preferred over Stack class.
[Hard] What is the difference between HashMap and TreeMap?
Ans: HashMap: unordered, O(1) ops, allows 1 null key. TreeMap: sorted by key (Red-Black Tree), O(log
n) ops, no null keys.
[Hard] What happens if two keys in HashMap have the same hashCode?
Ans: Hash collision. They go in the same bucket as a linked list (or tree if > 8). equals() is then used to
differentiate them.
[Medium] What is the diamond operator <> in Java 7+?
Ans: Allows type inference on the right side: List<String> list = new ArrayList<>(); Compiler infers the type
parameter, avoiding redundancy.
5.8 Coding Questions – Module 5
Q1. Create a generic Stack<T> class using ArrayList with push, pop, peek, isEmpty methods.
Hint: Generic class with ArrayList<T> internally
Q2. Store 10 Student objects in ArrayList. Sort by name, then by marks descending. Use both
Comparable and Comparator.
Hint: Student implements Comparable; also pass Comparator lambda to sort
Q3. Count word frequency in a sentence using HashMap. Print top 3 most frequent words.
Hint: getOrDefault pattern; sort entrySet by value
Q4. Create a TreeSet of Employees sorted by salary. Add duplicates and verify they are rejected.
Hint: Employee implements Comparable based on salary
Q5. Implement a queue system (Task Scheduler) using ArrayDeque: add tasks, process in FIFO order.
Hint: offer to back, poll from front
Q6. Use Deque as a stack to check if a string of brackets is balanced: () {} [].
Hint: push on open, pop and verify match on close
Q7. Write a generic method <T extends Comparable<T>> to find min and max in any List<T>.
Hint: Iterate; compare with Comparable
⚡ Quick Reference Cheat Sheet
Nested Class Selection Guide
Need Use
Helper class, no outer instance needed Static Nested Class
Need access to outer instance members Inner Class (non-static)
Scoped to a single method Local Class
One-time interface/abstract implementation Anonymous Class
One abstract method, use inline Lambda Expression
Built-in Functional Interfaces — Quick Ref
Interface Signature Returns Mnemonic
Predicate<T> test(T) boolean Test a condition
Function<T,R> apply(T) R Transform T to R
Consumer<T> accept(T) void Use/consume the value
Supplier<T> get() T Supply/provide a value
BinaryOperator<T> apply(T,T) T Combine two same-type values
Exception Types — Quick Ref
Type Subclass of Compiler Forces? Examples
Error Throwable No OutOfMemoryError,
StackOverflowError
Checked Exception Exception Yes IOException, SQLException
Unchecked Exception RuntimeException No NPE, ArrayIndexOutOfBounds
Collections — Quick Comparison
Collection Order Duplicates Null Complexity
ArrayList Insertion order Yes Yes Access O(1), Add O(1)
amort.
TreeSet Sorted No No O(log n) all ops
HashSet None No 1 null O(1) average
HashMap None Keys: No 1 null key O(1) average
TreeMap Sorted by key Keys: No No null key O(log n) all ops
ArrayDeque Both ends Yes No O(1) push/pop/peek
Common Mistakes to Avoid
• Using raw types (List instead of List<String>) — defeats generics purpose
• Catching Exception as the first catch block — hides specific handlers below
• Using assertions for argument validation in public methods — they are disabled by default
• Calling [Link](1) intending to remove value 1 — actually removes index 1
• Forgetting to sort before [Link]() — gives wrong results
• Using Stack class — prefer ArrayDeque (Stack is legacy, synchronized unnecessarily)
• Modifying a collection while iterating with for-each — ConcurrentModificationException
• Not implementing hashCode() when overriding equals() — breaks HashMap/HashSet
• Using SimpleDateFormat in multithreaded code — not thread-safe; use DateTimeFormatter
• Lambda capturing non-effectively-final variables — compile error
Every concept you master is a tool in your belt. Keep building. 🚀