Object Oriented Programming with Java
BCS – 403 | AKTU [Link] 2nd Year
Complete Exam-Ready Solutions
All 5 Units | Easy Language | Clean Code Examples
Target: 60–65 / 70 Marks
UNIT – I: Core Java & OOP Concepts
Q1. Explain the Java Compilation Process. Describe the roles of JVM, JRE, and JDK.
Java Compilation Process:
1. You write Java code in a .java file (source code).
2. The Java Compiler (javac) converts it into bytecode stored in a .class file.
3. The JVM (Java Virtual Machine) reads the .class file and converts bytecode to machine code at runtime (using
JIT compiler) and executes it.
Roles:
• JDK (Java Development Kit): Complete package for developers. Contains compiler (javac), JRE, and
development tools. You USE JDK to write and compile Java.
• JRE (Java Runtime Environment): Contains JVM + libraries. Needed to RUN Java programs. End users need
JRE.
• JVM (Java Virtual Machine): Executes the bytecode. Makes Java platform-independent (Write Once, Run
Anywhere). Handles memory, garbage collection, security.
✔ JDK ⊃ JRE ⊃ JVM (JDK contains JRE, JRE contains JVM)
Q2. Write the structure of a basic Java program. Label and explain each part.
// 1. Package declaration (optional)
package mypackage;
// 2. Import statements (optional)
import [Link];
// 3. Class declaration
public class HelloWorld {
// 4. Main method – entry point of the program
public static void main(String[] args) {
// 5. Statements / body
[Link]("Hello, World!");
}
}
Explanation of each part:
1. package: Groups related classes together.
2. import: Brings in external classes/libraries.
3. class: Blueprint/container for all code. File name must match class name.
4. main(): Starting point. JVM calls this first. Must be public static void.
5. Statements: Actual logic/output inside main.
Q3. What are constructors in Java? Differentiate between default, parameterized, and copy
constructors with examples.
Constructor: A special method with the same name as the class, called automatically when an object is created. It
initializes the object. It has NO return type.
class Student {
String name;
int age;
// 1. Default Constructor (no parameters)
Student() {
name = "Unknown";
age = 0;
}
// 2. Parameterized Constructor (takes parameters)
Student(String n, int a) {
name = n;
age = a;
}
// 3. Copy Constructor (copies another object)
Student(Student s) {
name = [Link];
age = [Link];
}
void display() {
[Link]("Name: " + name + ", Age: " + age);
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student(); // Default
Student s2 = new Student("Amit", 20); // Parameterized
Student s3 = new Student(s2); // Copy
[Link](); // Name: Unknown, Age: 0
[Link](); // Name: Amit, Age: 20
[Link](); // Name: Amit, Age: 20
}
}
Q4. Define method overloading and method overriding. Differentiate with suitable examples.
Method Overloading (Compile-time Polymorphism): Same method name, different parameters (number or
type), in the SAME class.
class Calculator {
int add(int a, int b) { return a + b; }
double add(double a, double b){ return a + b; }
int add(int a, int b, int c) { return a + b + c; }
}
Method Overriding (Runtime Polymorphism): Child class redefines a method from the parent class with the
SAME name and SAME parameters.
class Animal {
void sound() { [Link]("Some sound"); }
}
class Dog extends Animal {
@Override
void sound() { [Link]("Woof"); } // Overrides parent
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog();
[Link](); // Output: Woof
}
}
Key Differences: Overloading = same class, different params, compile-time. Overriding = different classes
(parent-child), same params, runtime.
Q5. Explain encapsulation in Java. How does Java support it? Write a program to illustrate
it.
Encapsulation means bundling data (variables) and methods together in a class and hiding data from outside
using private access modifier. Access is provided via public getters and setters.
Java supports encapsulation using: private variables + public getter/setter methods.
class BankAccount {
private double balance; // hidden from outside
// Getter
public double getBalance() {
return balance;
}
// Setter with validation
public void deposit(double amount) {
if (amount > 0)
balance += amount;
else
[Link]("Invalid amount!");
}
}
public class Main {
public static void main(String[] args) {
BankAccount acc = new BankAccount();
[Link](5000);
[Link]("Balance: " + [Link]());
// [Link] = -100; // ERROR! Cannot access directly
}
}
✔ Benefit: Data is protected. Outside code cannot corrupt it directly.
Q6. What is abstraction in Java? Explain with an abstract class and a subclass.
Abstraction means hiding implementation details and showing only the essential features. In Java, it is achieved
using abstract classes and interfaces.
An abstract class can have abstract methods (no body) and non-abstract methods. It cannot be instantiated
directly.
abstract class Shape {
// Abstract method – no body
abstract double area();
// Concrete method
void display() {
[Link]("Area = " + area());
}
}
class Circle extends Shape {
double r;
Circle(double r) { this.r = r; }
@Override
double area() { return 3.14 * r * r; }
}
class Rectangle extends Shape {
double l, b;
Rectangle(double l, double b) { this.l=l; this.b=b; }
@Override
double area() { return l * b; }
}
public class Main {
public static void main(String[] args) {
Shape s1 = new Circle(5);
Shape s2 = new Rectangle(4, 6);
[Link](); // Area = 78.5
[Link](); // Area = 24.0
}
}
Q7. What is the use of interfaces in Java? How are they different from abstract classes?
Interface: A blueprint with only abstract methods (before Java 8). It defines WHAT to do, not HOW. A class
implements an interface.
interface Printable {
void print(); // implicitly public and abstract
}
interface Showable {
void show();
}
// Java supports multiple interface implementation
class Document implements Printable, Showable {
public void print() { [Link]("Printing..."); }
public void show() { [Link]("Showing..."); }
}
Differences (Abstract Class vs Interface):
• Abstract class can have constructor; interface cannot.
• Abstract class can have instance variables; interface can only have static final (constants).
• A class can extend only ONE abstract class but implement MULTIPLE interfaces.
• Abstract class can have concrete methods; interface methods are abstract by default (Java 8+ allows
default/static methods).
Q8. Describe inheritance in Java. How is the 'super' keyword used in inheritance?
Inheritance: A child class (subclass) acquires properties and methods of a parent class (superclass) using the
extends keyword. Promotes code reuse.
Types: Single, Multilevel, Hierarchical (Java does NOT support multiple inheritance with classes).
super keyword uses: (1) Call parent constructor. (2) Call parent method. (3) Access parent variable.
class Animal {
String type = "Animal";
Animal(String name) {
[Link]("Animal: " + name);
}
void sound() { [Link]("Generic sound"); }
}
class Dog extends Animal {
Dog(String name) {
super(name); // Calls Animal's constructor
}
@Override
void sound() {
[Link](); // Calls Animal's sound()
[Link]("Woof!"); // Dog's own sound
}
void show() {
[Link]([Link]); // Accesses parent variable
}
}
public class Main {
public static void main(String[] args) {
Dog d = new Dog("Tommy");
[Link]();
[Link]();
}
}
Q9. Define static and final keywords in Java. Write a program using both.
static: Belongs to the class, not to any object. Shared among all instances. Called without creating object.
final: (1) final variable = constant (cannot change). (2) final method = cannot be overridden. (3) final class = cannot
be inherited.
class MathHelper {
static final double PI = 3.14159; // static + final = constant
static double circleArea(double r) { // static method
return PI * r * r;
}
}
public class Main {
public static void main(String[] args) {
// No object needed for static
[Link]("PI = " + [Link]);
[Link]("Area = " + [Link](5));
// [Link] = 3.0; // ERROR! final cannot be changed
}
}
Q10. Explain packages in Java. How is CLASSPATH set? How is a JAR file created?
Package: A folder/namespace that groups related classes. Avoids naming conflicts. Example: [Link], [Link].
// Creating a package
package [Link]; // at top of file
public class Helper {
public static void greet() {
[Link]("Hello from Helper!");
}
}
// Using the package
import [Link];
public class Main {
public static void main(String[] args) {
[Link]();
}
}
CLASSPATH: An environment variable that tells JVM where to find .class files and JAR files.
Set via command line: set CLASSPATH=.;C:\myproject\classes (Windows) or export
CLASSPATH=.:/myproject/classes (Linux)
JAR file creation: A JAR (Java ARchive) bundles multiple .class files into one. Commands:
# Compile
javac [Link]
# Create JAR
jar cf [Link] [Link]
# Run JAR
java -cp [Link] Main
UNIT – II: Exception Handling, I/O & Multithreading
Q1. Explain try, catch, finally, throw, and throws with syntax and example.
try: Block where risky code is placed. catch: Handles the exception if it occurs. finally: Always executes (cleanup
code). throw: Manually throws an exception. throws: Declares that a method may throw an exception.
public class ExceptionDemo {
// 'throws' declares the exception
static void checkAge(int age) throws Exception {
if (age < 18)
throw new Exception("Under 18!"); // 'throw' manually
[Link]("Access granted.");
}
public static void main(String[] args) {
try {
checkAge(15); // Risky code
} catch (Exception e) { // Handles exception
[Link]("Caught: " + [Link]());
} finally { // Always runs
[Link]("Program ends.");
}
}
}
// Output:
// Caught: Under 18!
// Program ends.
Q2. Difference between checked and unchecked exceptions.
Checked Exceptions: Checked at compile time. Must be handled using try-catch or throws. Example:
IOException, SQLException, FileNotFoundException.
Unchecked Exceptions: Checked at runtime. Subclass of RuntimeException. Not mandatory to handle. Example:
NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException.
// Checked Exception Example
import [Link].*;
public class CheckedDemo {
public static void main(String[] args) {
try {
FileReader f = new FileReader("[Link]"); // Compile error if not handled!
} catch (FileNotFoundException e) {
[Link]("File not found!");
}
}
}
// Unchecked Exception Example
public class UncheckedDemo {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
[Link](arr[5]); // ArrayIndexOutOfBoundsException at runtime
}
}
Q3. What is an ArithmeticException? Write a program to handle division by zero.
ArithmeticException is a runtime (unchecked) exception that occurs when an illegal arithmetic operation is
performed, like dividing an integer by zero.
public class DivisionDemo {
public static void main(String[] args) {
int a = 10, b = 0;
try {
int result = a / b; // This will throw ArithmeticException
[Link]("Result: " + result);
} catch (ArithmeticException e) {
[Link]("Error: " + [Link]()); // / by zero
} finally {
[Link]("Division attempted.");
}
}
}
// Output:
// Error: / by zero
// Division attempted.
Q4. Describe user-defined exceptions with a Java program to handle invalid age input.
User-defined exception: We create our own exception class by extending the Exception class. This helps handle
application-specific errors meaningfully.
// Step 1: Create custom exception class
class InvalidAgeException extends Exception {
InvalidAgeException(String message) {
super(message); // Pass message to parent
}
}
// Step 2: Use it in program
public class AgeValidator {
static void validateAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("Age " + age + " is not valid! Must be 18+");
}
[Link]("Valid age: " + age);
}
public static void main(String[] args) {
try {
validateAge(15);
} catch (InvalidAgeException e) {
[Link]("Custom Exception: " + [Link]());
}
}
}
// Output: Custom Exception: Age 15 is not valid! Must be 18+
Q5. What are byte streams and character streams? Compare with examples.
Byte Streams: Handle raw binary data (images, audio, video). Work with bytes (8-bit). Classes: InputStream,
OutputStream, FileInputStream, FileOutputStream.
Character Streams: Handle text data. Work with characters (16-bit Unicode). Classes: Reader, Writer, FileReader,
FileWriter.
// Byte Stream Example
import [Link].*;
public class ByteStreamDemo {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("[Link]");
[Link](65); // Writes byte value 65 (= 'A')
[Link]();
FileInputStream fis = new FileInputStream("[Link]");
int b = [Link]();
[Link]("Byte read: " + (char)b); // A
[Link]();
}
}
// Character Stream Example
import [Link].*;
public class CharStreamDemo {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("[Link]");
[Link]("Hello Java!"); // Writes text
[Link]();
FileReader fr = new FileReader("[Link]");
int ch;
while ((ch = [Link]()) != -1)
[Link]((char)ch);
[Link]();
}
}
Q6. Write a Java program to read a file using FileReader and write into another file using
FileWriter.
import [Link].*;
public class FileCopyDemo {
public static void main(String[] args) {
try {
// Read from source file
FileReader fr = new FileReader("[Link]");
// Write to destination file
FileWriter fw = new FileWriter("[Link]");
int ch;
while ((ch = [Link]()) != -1) {
[Link](ch); // Copy char by char
}
[Link]();
[Link]();
[Link]("File copied successfully!");
} catch (FileNotFoundException e) {
[Link]("Source file not found!");
} catch (IOException e) {
[Link]("IO Error: " + [Link]());
}
}
}
Q7. Describe the Thread life cycle with a suitable diagram.
Thread Life Cycle States:
1. New: Thread object is created but start() not called yet.
2. Runnable: start() is called. Thread is ready to run, waiting for CPU.
3. Running: CPU is executing the thread (run() method executing).
4. Blocked/Waiting: Thread is waiting (for I/O, sleep, or lock).
5. Terminated (Dead): Thread has finished execution or was stopped.
Thread Life Cycle (Diagram):
new Thread() start() CPU allocated
■■■■■■■■■■■ NEW ■■■■■■■■■■■ RUNNABLE ■■■■■■■■■■■ RUNNING
▲ ■
■ sleep/wait ends ■ sleep()/wait()/
■ ▼ blocked on I/O
■■■■■■■■■■■■■ BLOCKED/WAITING
■
run() finishes
▼
TERMINATED
Q8. What are the two ways of creating a thread in Java? Write examples for both.
Way 1: Extending the Thread class
class MyThread extends Thread {
public void run() {
for (int i = 1; i <= 3; i++)
[Link]("Thread: " + i);
}
}
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
[Link](); // Starts the thread
}
}
Way 2: Implementing the Runnable interface (Preferred)
class MyRunnable implements Runnable {
public void run() {
for (int i = 1; i <= 3; i++)
[Link]("Runnable: " + i);
}
}
public class Main {
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t = new Thread(r); // Pass Runnable to Thread
[Link]();
}
}
✔ Runnable is preferred because Java does not support multiple class inheritance.
Q9. Explain synchronization in multithreading. Write a Java program to demonstrate it.
Synchronization: When multiple threads access the same shared resource simultaneously, data inconsistency
can occur. Synchronization ensures only ONE thread accesses the resource at a time using the synchronized
keyword.
class Counter {
int count = 0;
// synchronized method - only one thread can enter at a time
synchronized void increment() {
count++;
}
}
public class SyncDemo {
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) [Link]();
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) [Link]();
});
[Link](); [Link]();
[Link](); [Link]();
[Link]("Final count: " + [Link]); // 2000 (correct!)
}
}
Q10. What is inter-thread communication? Explain wait(), notify(), and notifyAll() methods.
Inter-thread communication allows synchronized threads to communicate with each other to avoid polling (busy
waiting). These methods are in the Object class.
• wait(): Thread releases the lock and waits until notified.
• notify(): Wakes up ONE waiting thread.
• notifyAll(): Wakes up ALL waiting threads.
class SharedBox {
int item = 0;
boolean produced = false;
synchronized void produce(int val) throws InterruptedException {
while (produced)
wait(); // Wait if already produced
item = val;
produced = true;
[Link]("Produced: " + item);
notify(); // Notify consumer
}
synchronized void consume() throws InterruptedException {
while (!produced)
wait(); // Wait if nothing produced
[Link]("Consumed: " + item);
produced = false;
notify(); // Notify producer
}
}
public class Main {
public static void main(String[] args) {
SharedBox box = new SharedBox();
Thread producer = new Thread(() -> {
try { for(int i=1;i<=3;i++) [Link](i); }
catch(InterruptedException e) {}
});
Thread consumer = new Thread(() -> {
try { for(int i=1;i<=3;i++) [Link](); }
catch(InterruptedException e) {}
});
[Link]();
[Link]();
}
}
UNIT – III: Java 8+ Features & Modern Java
Q1. What is a Functional Interface? Give an example using @FunctionalInterface and
lambda expression.
Functional Interface: An interface with exactly ONE abstract method. The @FunctionalInterface annotation
ensures this rule. It enables the use of lambda expressions.
@FunctionalInterface
interface Greeting {
void greet(String name); // Only ONE abstract method
}
public class Main {
public static void main(String[] args) {
// Lambda expression implements the interface
Greeting g = (name) -> [Link]("Hello, " + name + "!");
[Link]("Rahul"); // Hello, Rahul!
// Another example with return value
@FunctionalInterface
interface MathOp { int operate(int a, int b); }
MathOp add = (a, b) -> a + b;
MathOp mul = (a, b) -> a * b;
[Link]("Add: " + [Link](3, 4)); // 7
[Link]("Mul: " + [Link](3, 4)); // 12
}
}
✔ Built-in functional interfaces: Runnable, Comparator, Predicate, Function, Consumer, Supplier
Q2. Describe lambda expressions in Java with suitable examples.
Lambda Expression: A short block of code to represent a function without a name. Used as a value passed to
functional interfaces. Introduced in Java 8.
Syntax: (parameters) -> expression OR (parameters) -> { statements; }
import [Link].*;
public class LambdaDemo {
public static void main(String[] args) {
// Example 1: No parameter
Runnable r = () -> [Link]("Lambda running!");
[Link]();
// Example 2: With parameter
List<String> names = [Link]("Priya", "Amit", "Zara");
[Link](name -> [Link]("Hello " + name));
// Example 3: Sort with lambda
[Link]((a, b) -> [Link](b));
[Link](names); // [Amit, Priya, Zara]
// Example 4: Lambda with block body
[Link](name -> {
String upper = [Link]();
[Link](upper);
});
}
}
Q3. Explain the Stream API in Java. Describe intermediate and terminal operations with
example.
Stream API (Java 8+): Allows functional-style operations on collections. A Stream is a sequence of elements
processed in a pipeline.
Intermediate Operations: Return a new stream, are lazy (not executed immediately). Examples: filter(), map(),
sorted(), distinct(), limit().
Terminal Operations: Trigger the stream processing and return a result. Examples: collect(), forEach(), count(),
reduce(), findFirst().
import [Link].*;
import [Link].*;
public class StreamDemo {
public static void main(String[] args) {
List<Integer> nums = [Link](5, 2, 8, 1, 9, 3, 7, 4, 6);
// Pipeline: filter → map → sorted → collect
List<Integer> result = [Link]()
.filter(n -> n % 2 == 0) // Intermediate: keep even numbers
.map(n -> n * n) // Intermediate: square each
.sorted() // Intermediate: sort
.collect([Link]()); // Terminal: collect to list
[Link](result); // [4, 16, 36, 64]
// Count even numbers
long count = [Link]()
.filter(n -> n % 2 == 0)
.count(); // Terminal operation
[Link]("Even count: " + count); // 4
}
}
Q4. Write a Java program to compute the sum of even numbers from a List using streams.
import [Link].*;
import [Link].*;
public class SumEvenStream {
public static void main(String[] args) {
List<Integer> numbers = [Link](1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = [Link]()
.filter(n -> n % 2 == 0) // Keep even numbers: 2,4,6,8,10
.mapToInt(Integer::intValue) // Convert to int stream
.sum(); // Terminal: sum all
[Link]("Sum of even numbers: " + sum); // 30
}
}
Q5. What are method references? Explain the syntax with an example.
Method Reference: A shorter way to write a lambda that just calls an existing method. Uses :: operator. Makes
code cleaner and more readable.
Types:
1. Static method: ClassName::staticMethod
2. Instance method of object: obj::instanceMethod
3. Instance method of class: ClassName::instanceMethod
4. Constructor: ClassName::new
import [Link].*;
public class MethodRefDemo {
public static void main(String[] args) {
List<String> names = [Link]("Alice", "Bob", "Charlie");
// Lambda version
[Link](name -> [Link](name));
// Method reference version (cleaner!)
[Link]([Link]::println); // instance method of object
// Static method reference
List<Integer> nums = [Link](3, 1, 4, 1, 5);
[Link](Integer::compare); // same as (a,b) -> [Link](a,b)
[Link](nums); // [1, 1, 3, 4, 5]
}
}
Q6. Compare switch statement and switch expression in Java. Provide an example of each.
// Traditional switch STATEMENT (older style)
public class SwitchDemo {
public static void main(String[] args) {
int day = 3;
// Switch Statement
switch (day) {
case 1: [Link]("Monday"); break;
case 2: [Link]("Tuesday"); break;
case 3: [Link]("Wednesday"); break;
default: [Link]("Other");
}
// Switch EXPRESSION (Java 14+) – cleaner, no break needed
String dayName = switch (day) {
case 1 -> "Monday";
case 2 -> "Tuesday";
case 3 -> "Wednesday";
default -> "Other";
};
[Link](dayName); // Wednesday
}
}
Key difference: Switch expression returns a value and uses -> arrow syntax. No fall-through. More concise.
Q7. What are text blocks in Java? How are they useful? Give a code example.
Text Block (Java 15+): A multi-line string literal enclosed in triple quotes """. It avoids the need for escape
characters and makes multi-line strings (HTML, JSON, SQL) easy to write.
public class TextBlockDemo {
public static void main(String[] args) {
// Without text block (messy)
String oldJson = "{\n \"name\": \"Rahul\",\n \"age\": 20\n}";
// With text block (clean!)
String json = """
{
"name": "Rahul",
"age": 20
}
""";
[Link](json);
// HTML example
String html = """
<html>
<body>
<p>Hello!</p>
</body>
</html>
""";
[Link](html);
}
}
Q8. Explain the concept of sealed classes. How are they declared and used?
Sealed Classes (Java 17+): A class that restricts which other classes can extend (inherit) it. Declared using
sealed keyword and permits clause. Provides better control over class hierarchy.
// Sealed class - only Circle and Rectangle can extend it
sealed class Shape permits Circle, Rectangle {
abstract double area();
}
// Must be final, sealed, or non-sealed
final class Circle extends Shape {
double r;
Circle(double r) { this.r = r; }
double area() { return 3.14 * r * r; }
}
final class Rectangle extends Shape {
double l, b;
Rectangle(double l, double b) { this.l=l; this.b=b; }
double area() { return l * b; }
}
// This would cause ERROR:
// class Triangle extends Shape { } // Not in permits list!
public class Main {
public static void main(String[] args) {
Shape s1 = new Circle(5);
Shape s2 = new Rectangle(4, 6);
[Link]([Link]()); // 78.5
[Link]([Link]()); // 24.0
}
}
Q9. What is the purpose of try-with-resources in Java? Write an example using
BufferedReader.
try-with-resources (Java 7+): Automatically closes resources (like files, connections) after the try block ends. The
resource must implement the AutoCloseable interface. Eliminates the need for explicit finally block to close
resources.
import [Link].*;
public class TryWithResourcesDemo {
public static void main(String[] args) {
// Resource is declared inside try() - auto-closed!
try (BufferedReader br = new BufferedReader(new FileReader("[Link]"))) {
String line;
while ((line = [Link]()) != null) {
[Link](line);
}
// [Link]() is called AUTOMATICALLY here
} catch (IOException e) {
[Link]("Error: " + [Link]());
}
// No need for finally block to close br!
}
}
✔ Multiple resources: try (Res1 r1 = ...; Res2 r2 = ...) - both closed automatically in reverse order.
Q10. Describe records in Java. How are they different from traditional classes?
Records (Java 16+): A concise way to create immutable data-holding classes. Java automatically generates
constructor, getters, equals(), hashCode(), and toString() methods.
// Traditional class - lots of boilerplate code
class PersonClass {
private final String name;
private final int age;
PersonClass(String name, int age) { [Link]=name; [Link]=age; }
String getName() { return name; }
int getAge() { return age; }
public String toString() { return "Person{name="+name+", age="+age+"}"; }
}
// Record - same functionality, much less code!
record Person(String name, int age) {}
public class Main {
public static void main(String[] args) {
Person p = new Person("Rahul", 20);
[Link]([Link]()); // Rahul (accessor, not getXxx)
[Link]([Link]()); // 20
[Link](p); // Person[name=Rahul, age=20]
}
}
Records are immutable (no setters), concise, and perfect for DTOs (Data Transfer Objects).
UNIT – IV: Java Collections Framework
Q1. Explain the Java Collections Framework with the hierarchy of interfaces and classes.
Java Collections Framework (JCF): A set of classes and interfaces to store and manipulate groups of objects
efficiently.
Collection Hierarchy:
[Link] (interface)
■■■ List (interface) - Ordered, allows duplicates
■ ■■■ ArrayList - Dynamic array, fast access
■ ■■■ LinkedList - Doubly linked list
■ ■■■ Vector - Thread-safe ArrayList
■
■■■ Set (interface) - No duplicates
■ ■■■ HashSet - Unordered, uses hashing
■ ■■■ LinkedHashSet - Insertion-ordered
■ ■■■ TreeSet - Sorted order
■
■■■ Queue (interface) - FIFO order
■■■ LinkedList - Can be used as Queue
■■■ PriorityQueue - Based on priority
[Link] (separate hierarchy, not under Collection)
■■■ HashMap - Key-value, unordered
■■■ LinkedHashMap - Insertion-ordered
■■■ TreeMap - Sorted by key
■■■ Hashtable - Thread-safe HashMap
Q2. Compare List, Set, and Queue interfaces. Give one implementation example of each.
import [Link].*;
public class CollectionCompare {
public static void main(String[] args) {
// LIST - ordered, allows duplicates
List<String> list = new ArrayList<>();
[Link]("A"); [Link]("B"); [Link]("A"); // Duplicate allowed
[Link]("List: " + list); // [A, B, A]
// SET - no duplicates, unordered
Set<String> set = new HashSet<>();
[Link]("A"); [Link]("B"); [Link]("A"); // Duplicate ignored
[Link]("Set: " + set); // [A, B] (order may vary)
// QUEUE - FIFO (First In, First Out)
Queue<String> queue = new LinkedList<>();
[Link]("First"); [Link]("Second"); [Link]("Third");
[Link]("Queue front: " + [Link]()); // First
[Link]("Removed: " + [Link]()); // First
[Link]("Queue: " + queue); // [Second, Third]
}
}
Q3. Write a Java program to store five names in an ArrayList and print using forEach()
method.
import [Link];
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
// Add 5 names
[Link]("Rahul");
[Link]("Priya");
[Link]("Amit");
[Link]("Sneha");
[Link]("Vikas");
[Link]("Students list:");
// Print using forEach with lambda
[Link](name -> [Link]("- " + name));
// Also works with method reference
// [Link]([Link]::println);
[Link]("Total students: " + [Link]());
}
}
// Output:
// Students list:
// - Rahul
// - Priya ...etc
Q4. What are the main features of LinkedList class? Explain any five methods with example.
LinkedList implements both List and Deque interfaces. It is a doubly-linked list (each element has a reference to
both previous and next). Useful when frequent insertions/deletions are needed.
import [Link];
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList<String> ll = new LinkedList<>();
// 1. add() - adds to end
[Link]("Banana");
[Link]("Cherry");
// 2. addFirst() - adds at beginning
[Link]("Apple");
[Link]("After addFirst: " + ll); // [Apple, Banana, Cherry]
// 3. addLast() - adds at end
[Link]("Date");
[Link]("After addLast: " + ll); // [Apple, Banana, Cherry, Date]
// 4. removeFirst() - removes from beginning
[Link]();
[Link]("After removeFirst: " + ll); // [Banana, Cherry, Date]
// 5. getFirst() / getLast() - peek without removing
[Link]("First: " + [Link]()); // Banana
[Link]("Last: " + [Link]()); // Date
// 6. size()
[Link]("Size: " + [Link]()); // 3
}
}
Q5. Write a Java program that uses HashMap to store roll number and name of students.
import [Link];
import [Link];
public class HashMapDemo {
public static void main(String[] args) {
HashMap<Integer, String> students = new HashMap<>();
// Store: rollNumber -> name
[Link](101, "Rahul Sharma");
[Link](102, "Priya Singh");
[Link](103, "Amit Kumar");
[Link](104, "Sneha Verma");
// Access by key
[Link]("Roll 102: " + [Link](102));
// Print all entries
[Link]("\nAll Students:");
for ([Link]<Integer, String> entry : [Link]()) {
[Link]("Roll: " + [Link]() + " | Name: " + [Link]());
}
// Check if key exists
[Link]("\nRoll 103 exists: " + [Link](103));
// Remove a student
[Link](101);
[Link]("After removal, size: " + [Link]());
}
}
Q6. Compare HashSet, LinkedHashSet, and TreeSet with respect to ordering and
performance.
import [Link].*;
public class SetComparison {
public static void main(String[] args) {
// HashSet - NO guaranteed order, fastest
Set<Integer> hashSet = new HashSet<>();
[Link](30); [Link](10); [Link](20);
[Link]("HashSet: " + hashSet); // Order may vary
// LinkedHashSet - INSERTION ORDER maintained
Set<Integer> linkedSet = new LinkedHashSet<>();
[Link](30); [Link](10); [Link](20);
[Link]("LinkedHashSet: " + linkedSet); // [30, 10, 20]
// TreeSet - SORTED order (ascending by default)
Set<Integer> treeSet = new TreeSet<>();
[Link](30); [Link](10); [Link](20);
[Link]("TreeSet: " + treeSet); // [10, 20, 30]
}
}
// Summary:
// HashSet → Unordered, O(1) add/get, uses hashing
// LinkedHashSet → Insertion ordered, slightly slower than HashSet
// TreeSet → Sorted order, O(log n) operations, uses Red-Black Tree
Q7. Differentiate between Comparable and Comparator with examples.
Comparable: Interface in [Link]. Class defines its OWN natural sorting. Uses compareTo(). Class itself is
modified.
Comparator: Interface in [Link]. Used to define EXTERNAL/CUSTOM sorting logic. Uses compare(). Original
class is NOT modified.
import [Link].*;
// Using Comparable - natural order by age
class Student implements Comparable<Student> {
String name; int age;
Student(String n, int a) { name=n; age=a; }
public int compareTo(Student s) { return [Link] - [Link]; } // sort by age
public String toString() { return name+"("+age+")"; }
}
// Using Comparator - custom order by name
class NameComparator implements Comparator<Student> {
public int compare(Student s1, Student s2) {
return [Link]([Link]); // sort by name
}
}
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
[Link](new Student("Zara", 22));
[Link](new Student("Amit", 19));
[Link](new Student("Priya", 21));
[Link](students); // Uses Comparable (by age)
[Link]("By age: " + students);
[Link](new NameComparator()); // Uses Comparator (by name)
[Link]("By name: " + students);
}
}
Q8. What is the use of the Properties class in Java? Write a code to read/write .properties
file.
Properties class is a subclass of Hashtable used to store configuration data as key-value pairs in a .properties
file. Commonly used for app settings, database config, etc.
import [Link];
import [Link].*;
public class PropertiesDemo {
public static void main(String[] args) throws IOException {
Properties props = new Properties();
// Write properties to file
[Link]("[Link]", "jdbc:mysql://localhost/mydb");
[Link]("[Link]", "root");
[Link]("[Link]", "1234");
FileOutputStream fos = new FileOutputStream("[Link]");
[Link](fos, "Database Configuration"); // Save to file
[Link]();
[Link]("Properties saved!");
// Read properties from file
Properties loadedProps = new Properties();
FileInputStream fis = new FileInputStream("[Link]");
[Link](fis);
[Link]();
[Link]("DB URL: " + [Link]("[Link]"));
[Link]("User: " + [Link]("[Link]"));
}
}
Q9. What are iterators in Java? How is Iterator interface used to traverse a List?
Iterator: An interface ([Link]) that provides a way to traverse a collection one element at a time. It is safer
than for loops when removing elements during iteration.
Key methods: hasNext() – returns true if more elements exist. next() – returns the next element. remove() –
removes the last element returned.
import [Link].*;
public class IteratorDemo {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
[Link]("Apple");
[Link]("Banana");
[Link]("Mango");
[Link]("Orange");
// Get iterator
Iterator<String> it = [Link]();
[Link]("Fruits:");
while ([Link]()) { // Check if next exists
String fruit = [Link](); // Get next element
[Link](fruit);
// Safe removal during iteration
if ([Link]("Banana")) {
[Link](); // Remove "Banana" safely
}
}
[Link]("After removal: " + fruits);
}
}
Q10. What is a TreeMap? Write a Java program to create and display a TreeMap.
TreeMap: A Map implementation that stores key-value pairs in sorted (ascending) order of keys. It is based on a
Red-Black Tree. Does NOT allow null keys. Slightly slower than HashMap.
import [Link];
import [Link];
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<Integer, String> treeMap = new TreeMap<>();
// Adding entries (keys in random order)
[Link](103, "Amit");
[Link](101, "Rahul");
[Link](105, "Zara");
[Link](102, "Priya");
[Link](104, "Sneha");
// TreeMap automatically sorts by key
[Link]("Sorted by Roll Number:");
for ([Link]<Integer, String> e : [Link]()) {
[Link]("Roll " + [Link]() + ": " + [Link]());
}
// Special methods
[Link]("First key: " + [Link]()); // 101
[Link]("Last key: " + [Link]()); // 105
[Link]("Keys < 103: " + [Link](103)); // {101,102}
}
}
UNIT – V: Spring Framework & Spring Boot
Q1. What is Spring Framework? Explain Dependency Injection and Inversion of Control.
Spring Framework: A powerful, open-source Java framework for building enterprise applications. It simplifies
development by providing features like DI, AOP, MVC, etc.
Inversion of Control (IoC): Instead of you creating objects manually, the Spring Container creates and manages
objects (beans) for you. Control is INVERTED – you don't control object creation, Spring does.
Dependency Injection (DI): A form of IoC. Instead of a class creating its own dependencies, they are INJECTED
from outside (by Spring). Types: Constructor Injection, Setter Injection, Field Injection.
// Without DI (tight coupling - bad)
class OrderService {
PaymentService ps = new PaymentService(); // Created manually
}
// With DI (loose coupling - good)
@Service
class OrderService {
@Autowired
PaymentService ps; // Injected by Spring automatically
// Spring creates PaymentService and injects it here
}
Benefit: Loose coupling, easier testing, more flexible code.
Q2. Describe Spring Bean lifecycle with a suitable diagram and code example.
A Spring Bean is an object managed by the Spring IoC Container. The lifecycle goes through several stages:
Bean Lifecycle Stages:
1. Bean Definition loaded from config/annotations
2. Bean Instantiation (object created)
3. Properties Injected (DI performed)
4. setBeanName() called (BeanNameAware)
5. setBeanFactory() called (BeanFactoryAware)
6. postProcessBeforeInitialization() [BeanPostProcessor]
7. @PostConstruct / afterPropertiesSet() [InitializingBean]
8. Custom init-method called
■■■ BEAN IS READY FOR USE ■■■
9. Bean used by application
10. @PreDestroy / destroy() called
11. Custom destroy-method called
12. Bean destroyed
import [Link].*;
import [Link];
@Component
public class MyBean {
@PostConstruct // Called after DI is complete
public void init() {
[Link]("Bean initialized!");
}
public void doWork() {
[Link]("Bean is working...");
}
@PreDestroy // Called before bean is destroyed
public void cleanup() {
[Link]("Bean destroyed!");
}
}
Q3. Explain the concept of bean scopes in Spring. Describe singleton and prototype scopes.
Bean Scope defines how many instances of a bean Spring creates and how long they live.
1. Singleton (Default): Only ONE instance of the bean is created per Spring container. The same object is
returned every time. Best for stateless beans.
2. Prototype: A NEW instance is created every time the bean is requested. Best for stateful beans.
import [Link].*;
@Configuration
public class AppConfig {
@Bean
@Scope("singleton") // Default - one instance
public SingletonBean singletonBean() {
return new SingletonBean();
}
@Bean
@Scope("prototype") // New instance each time
public PrototypeBean prototypeBean() {
return new PrototypeBean();
}
}
// Usage
@Component
public class Demo {
@Autowired ApplicationContext ctx;
public void test() {
// Singleton - same object both times
SingletonBean s1 = [Link]([Link]);
SingletonBean s2 = [Link]([Link]);
[Link](s1 == s2); // true (same object)
// Prototype - different objects each time
PrototypeBean p1 = [Link]([Link]);
PrototypeBean p2 = [Link]([Link]);
[Link](p1 == p2); // false (different objects)
}
}
✔ Other scopes: request, session, application (for web apps)
Q4. What are annotations in Spring? List and explain commonly used Spring Core
annotations.
Annotations are metadata tags that tell Spring how to manage your classes and beans. They replace XML
configuration.
Commonly used Spring Core Annotations:
@Component – Marks class as a Spring bean (general purpose)
@Service – Marks service layer classes (@Component + semantic meaning)
@Repository – Marks DAO/data layer classes (also enables exception translation)
@Controller – Marks MVC controller classes
@RestController – @Controller + @ResponseBody (for REST APIs)
@Autowired – Automatically injects a dependency (by type)
@Qualifier("x") – Specifies which bean to inject when multiple exist
@Value("${key}") – Injects a value from properties file
@Configuration – Marks class as source of bean definitions
@Bean – Method produces a Spring bean
@ComponentScan – Tells Spring where to look for components
@Scope – Defines bean scope (singleton, prototype, etc.)
@PostConstruct – Method called after bean initialization
@PreDestroy – Method called before bean destruction
// Example showing key annotations
@Configuration
@ComponentScan(basePackages = "[Link]")
public class AppConfig { }
@Service
public class UserService {
@Autowired
private UserRepository repo;
@Value("${[Link]}")
private String appName;
}
Q5. Differentiate between Spring configuration styles: XML, Annotation, and Java-based.
// 1. XML-based Configuration (Traditional way)
// In [Link]:
// <bean id="myBean" class="[Link]">
// <property name="message" value="Hello!"/>
// </bean>
// 2. Annotation-based Configuration
// Spring scans classes with @Component, @Service, etc.
@Component
public class MyService {
@Autowired
MyRepository repo; // DI via annotation
}
// Need: @ComponentScan in config
// 3. Java-based Configuration (Modern, preferred)
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService(); // Explicit bean definition in Java
}
}
Summary:
• XML: No recompilation needed, but verbose and error-prone.
• Annotation: Less code, but tightly couples Spring with business code.
• Java-based: Type-safe, IDE-friendly, modern preferred approach.
Q6. What is Spring Boot? List its benefits over traditional Spring applications.
Spring Boot is a framework built on top of Spring that makes it easy to create stand-alone, production-ready
Spring applications with minimal configuration. It eliminates boilerplate setup.
Benefits of Spring Boot over traditional Spring:
1. Auto-configuration: Automatically configures Spring based on the JARs on the classpath. No manual XML
setup needed.
2. Embedded server: Comes with Tomcat/Jetty built-in. No need to deploy WAR to external server.
3. Starter dependencies: Pre-packaged dependency groups (spring-boot-starter-web,
spring-boot-starter-data-jpa, etc.).
4. Spring Initializr: Online project generator to quickly bootstrap apps.
5. Actuator: Built-in monitoring and health-check endpoints.
6. Less boilerplate code: No [Link], no DispatcherServlet config.
// Minimum Spring Boot app:
@SpringBootApplication // Combines @Configuration, @EnableAutoConfig, @ComponentScan
public class MyApp {
public static void main(String[] args) {
[Link]([Link], args); // Starts app!
}
}
Q7. What are Spring Boot Starters and Spring Initializer?
Spring Boot Starters: Pre-configured dependency packages that bundle all related libraries needed for a specific
feature. Instead of adding 10 individual dependencies, you add ONE starter.
<!-- In [Link] - Just ONE dependency for web development -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- This automatically includes: Spring MVC, Jackson, Tomcat, etc. -->
</dependency>
<!-- Common Starters: -->
<!-- spring-boot-starter-web → For REST APIs and web apps -->
<!-- spring-boot-starter-data-jpa → For database with JPA/Hibernate -->
<!-- spring-boot-starter-security → For Spring Security -->
<!-- spring-boot-starter-test → For testing (JUnit, Mockito) -->
<!-- spring-boot-starter-thymeleaf → For HTML templates -->
Spring Initializr ([Link]): A web-based tool to quickly generate a Spring Boot project skeleton. You select:
Project type (Maven/Gradle), Java version, dependencies (starters), and it generates a ready-to-import ZIP file.
Q8. How to build a RESTful web service using Spring Boot? Explain.
REST (Representational State Transfer) is an architectural style for APIs. Spring Boot makes it easy with
@RestController.
// 1. Add dependency in [Link]
// spring-boot-starter-web
// 2. Create the model class
public class Student {
private int id;
private String name;
// constructor, getters, setters
public Student(int id, String name) { [Link]=id; [Link]=name; }
public int getId() { return id; }
public String getName() { return name; }
}
// 3. Create REST Controller
import [Link].*;
import [Link].*;
@RestController // Marks as REST API controller
@RequestMapping("/api") // Base URL path
public class StudentController {
// GET all students
@GetMapping("/students")
public List<Student> getStudents() {
return [Link](
new Student(1, "Rahul"),
new Student(2, "Priya")
);
}
// GET student by ID
@GetMapping("/students/{id}")
public Student getById(@PathVariable int id) {
return new Student(id, "Student " + id);
}
// POST - add new student
@PostMapping("/students")
public String addStudent(@RequestBody Student s) {
return "Added: " + [Link]();
}
}
// 4. Main class
@SpringBootApplication
public class App {
public static void main(String[] args) {
[Link]([Link], args);
}
}
// Run on: [Link]
Q9. How are path variables and request parameters handled in Spring Boot? Provide code
snippets.
@PathVariable: Extracts value from the URL path itself. URL: /students/101 → id = 101.
@RequestParam: Extracts value from query parameters (after ?). URL: /students?name=Rahul&age;=20 →
name="Rahul", age=20.
@RestController
@RequestMapping("/api")
public class DemoController {
// PATH VARIABLE - value in the URL path
// URL: GET /api/students/101
@GetMapping("/students/{id}")
public String getStudent(@PathVariable int id) {
return "Student with ID: " + id;
}
// Multiple path variables
// URL: GET /api/students/CSE/Sem4
@GetMapping("/students/{branch}/{semester}")
public String getByBranchSem(@PathVariable String branch,
@PathVariable String semester) {
return "Branch: " + branch + ", Semester: " + semester;
}
// REQUEST PARAMETER - value after '?'
// URL: GET /api/search?name=Rahul&city=Agra
@GetMapping("/search")
public String search(@RequestParam String name,
@RequestParam(required = false, defaultValue = "India") String city) {
return "Name: " + name + ", City: " + city;
}
}
Q10. Write a Spring Boot application to accept a user's details (name and age) and return
them in the response.
// 1. Model class
public class User {
private String name;
private int age;
// Default constructor (needed for JSON deserialization)
public User() {}
public User(String name, int age) {
[Link] = name;
[Link] = age;
}
// Getters and Setters
public String getName() { return name; }
public void setName(String name) { [Link] = name; }
public int getAge() { return age; }
public void setAge(int age) { [Link] = age; }
}
// 2. Controller
import [Link].*;
@RestController
@RequestMapping("/api/users")
public class UserController {
// Accept via request params (GET request)
// URL: GET /api/users/get?name=Rahul&age=20
@GetMapping("/get")
public User getUserByParams(@RequestParam String name,
@RequestParam int age) {
return new User(name, age);
}
// Accept via request body (POST request with JSON body)
// Body: {"name": "Rahul", "age": 20}
@PostMapping("/create")
public User createUser(@RequestBody User user) {
// Return the received user details
return user;
}
}
// 3. Main Application
import [Link];
import [Link];
@SpringBootApplication
public class UserApp {
public static void main(String[] args) {
[Link]([Link], args);
}
}
// Test GET: [Link]
// Response: {"name":"Rahul","age":20}
// Test POST: [Link]
// Body: {"name":"Priya","age":22}
// Response: {"name":"Priya","age":22}
Best of Luck for Your Exam!
Key Tips to Score 60-65/70:
■ Write the definition clearly, then go straight to code example.
■ Every answer with code should compile in your mind — keep it simple.
■ For 7-8 mark questions: Definition + Points + Code = Full marks.
■ Draw diagrams for Thread lifecycle and Collection hierarchy.
■ Spring Boot questions: Focus on annotations and code snippets.
■ Revise Unit 1 (OOP concepts) and Unit 4 (Collections) the most — heavy weightage.
■ Write method signatures correctly — examiners check them!