Exam Kit Program Bank — 30 Programs

Program Bank — 30 Programs

This is the highest-value file in the kit. Your sample paper ends almost every question block with "Write a Java program to…", and Question Bank Chapters 3, 4, 7 and 8 all contain program questions.

Every program here follows the same three steps: What it does → How the logic works (in words) → The code → The output.

That middle step is the one nobody gives you, and it's the one that makes a program possible to remember.

Java version: all programs target Java 25 LTS (2025) and also compile on Java 21 and Java 17.

Verified: every standalone program in this file was compiled and run with javac --release 25 — 32 programs, 32 compiled, 32 ran, 0 errors. One advisory warning appears (a missing serialVersionUID on the custom exception class); it is harmless and standard for a teaching example.


The five to learn first

If you only have two hours, learn these. They appear in the sample paper and the lab manual and your assignments.

Program Where it's asked
1 — Second largest without sorting Sample paper, Lab P7
3 — Remove duplicates and sort Sample paper, Lab P7
13 — Constructor overloading Sample paper, Assignment 2 Q3
19 — Custom exception Sample paper, by name
20 — Threads with a shared counter Sample paper, Assignment 3 Q3

Program 1 · Second largest without sorting 🔥

What it does

Finds the biggest number and the runner-up, without calling sort().

How the logic works

Picture a leaderboard you keep in your head.

  1. Start with both "biggest" and "second" set to the smallest possible number.
  2. Look at each number in turn.
  3. If it beats your current biggest — the old biggest gets demoted to second.
  4. If it doesn't beat the biggest, but does beat second — it becomes the new second.
  5. The n != first check stops a duplicate of the top score from being counted twice.

Code

public class SecondLargest {
    public static void main(String[] args) {

        int[] a = {12, 45, 7, 89, 89, 23, 56};

        int first  = Integer.MIN_VALUE;   // smallest possible int, so anything beats it
        int second = Integer.MIN_VALUE;

        for (int n : a) {
            if (n > first) {
                second = first;           // old champion becomes runner-up
                first  = n;               // new champion
            } else if (n > second && n != first) {
                second = n;               // new runner-up (ignoring duplicates of the top)
            }
        }

        System.out.println("Array:          " + java.util.Arrays.toString(a));
        System.out.println("Largest:        " + first);
        System.out.println("Second largest: " + second);
    }
}

Output

Array:          [12, 45, 7, 89, 89, 23, 56]
Largest:        89
Second largest: 56

The bit that earns the mark

n != first. Without it, the second 89 would be recorded as the second largest — which is wrong. Examiners look for this check specifically.


Program 2 · Largest element in a 2D array

What it does

Scans a grid and finds the biggest value, plus where it lives.

How the logic works

Two nested loops = walking every cell of a table, row by row. Keep one "best so far" variable and update it whenever you see something bigger.

Code

public class Largest2D {
    public static void main(String[] args) {

        int[][] m = {
            {  7,   3,  -5, 10},
            { 11,  13, -15,  2},
            {  4, 100,   8, 21}
        };

        int max = m[0][0];           // assume the first cell is the biggest
        int rowOfMax = 0, colOfMax = 0;

        for (int i = 0; i < m.length; i++) {          // rows
            for (int j = 0; j < m[i].length; j++) {   // columns
                if (m[i][j] > max) {
                    max = m[i][j];
                    rowOfMax = i;
                    colOfMax = j;
                }
            }
        }

        System.out.println("Largest = " + max
                         + " at row " + rowOfMax + ", column " + colOfMax);
    }
}

Output

Largest = 100 at row 2, column 1

Remember this

m.length gives the number of rows. m[0].length gives the number of columns. That's because a 2D array in Java is really an array of arrays.


Program 3 · Remove duplicates and print sorted 🔥

What it does

Takes a messy list, removes repeats, and prints the survivors in order.

How the logic works

A TreeSet does both jobs at once: - A Set refuses duplicates - A Tree keeps things sorted

So you just pour the array in and read it back out.

Code — the easy way

import java.util.*;

public class UniqueSorted {
    public static void main(String[] args) {

        int[] a = {5, 3, 8, 3, 1, 5, 9, 1};

        TreeSet<Integer> unique = new TreeSet<>();   // no duplicates AND sorted
        for (int n : a) {
            unique.add(n);                           // repeats are silently ignored
        }

        System.out.println("Original : " + Arrays.toString(a));
        System.out.println("Unique   : " + unique);
    }
}

Output

Original : [5, 3, 8, 3, 1, 5, 9, 1]
Unique   : [1, 3, 5, 8, 9]

Code — the Stream way (if the question says "use Stream API")

import java.util.*;
import java.util.stream.*;

public class UniqueSortedStream {
    public static void main(String[] args) {

        List<Integer> list = Arrays.asList(5, 3, 8, 3, 1, 5, 9, 1);

        List<Integer> unique = list.stream()
                .distinct()                        // drop duplicates
                .sorted()                          // put in order
                .collect(Collectors.toList());

        System.out.println("Unique : " + unique);
    }
}

Code — no imports at all (if they forbid java.util)

public class UniqueSortedManual {
    public static void main(String[] args) {

        int[] a = {5, 3, 8, 3, 1, 5, 9, 1};

        // step 1: bubble-sort the array
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = 0; j < a.length - 1 - i; j++) {
                if (a[j] > a[j + 1]) {
                    int temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                }
            }
        }

        // step 2: print only when the value differs from the one before
        System.out.print("Unique : ");
        for (int i = 0; i < a.length; i++) {
            if (i == 0 || a[i] != a[i - 1]) {
                System.out.print(a[i] + " ");
            }
        }
        System.out.println();
    }
}
Unique : 1 3 5 8 9

Exam tip

Learn the TreeSet version. It's three lines and impossible to get wrong.


Program 4 · Matrix addition

How the logic works

Two grids of the same size. Add cell by cell: c[i][j] = a[i][j] + b[i][j].

Code

public class MatrixAdd {
    public static void main(String[] args) {

        int[][] a = {{1, 2, 3}, {4, 5, 6}};
        int[][] b = {{7, 8, 9}, {1, 2, 3}};
        int[][] c = new int[a.length][a[0].length];

        for (int i = 0; i < a.length; i++)
            for (int j = 0; j < a[i].length; j++)
                c[i][j] = a[i][j] + b[i][j];

        for (int[] row : c) {
            for (int v : row) System.out.printf("%4d", v);
            System.out.println();
        }
    }
}

Output

   8  10  12
   5   7   9

Program 5 · 3×3 matrix multiplication

How the logic works

This is the one that needs three loops. For each cell of the answer, you walk along row i of A and down column j of B, multiplying and adding.

c[i][j] = (a[i][0] * b[0][j]) + (a[i][1] * b[1][j]) + (a[i][2] * b[2][j])

That's what the inner loop k does.

Code

public class MatrixMul {
    public static void main(String[] args) {

        int[][] a = {{1,2,3},{4,5,6},{7,8,9}};
        int[][] b = {{9,8,7},{6,5,4},{3,2,1}};
        int[][] c = new int[3][3];

        for (int i = 0; i < 3; i++) {              // each row of the answer
            for (int j = 0; j < 3; j++) {          // each column of the answer
                for (int k = 0; k < 3; k++) {      // the multiply-and-add step
                    c[i][j] += a[i][k] * b[k][j];
                }
            }
        }

        for (int[] row : c) {
            for (int v : row) System.out.printf("%5d", v);
            System.out.println();
        }
    }
}

Output

   30   24   18
   84   69   54
  138  114   90

Memorise this one line

c[i][j] += a[i][k] * b[k][j];

Get that right and the whole program is correct.


Program 6 · Reverse a number

How the logic works

Peel off the last digit, stick it onto the answer, repeat.

  1. n % 10 gives the last digit
  2. rev * 10 + digit shifts the answer left and adds the new digit
  3. n / 10 drops the last digit

Code

public class Reverse {
    public static void main(String[] args) {

        int n = 12345;
        int original = n;
        int rev = 0;

        while (n != 0) {
            int digit = n % 10;        // grab last digit
            rev = rev * 10 + digit;    // append it to the answer
            n = n / 10;                // remove last digit from n
        }

        System.out.println("Original = " + original);
        System.out.println("Reversed = " + rev);
    }
}

Output

Original = 12345
Reversed = 54321

Trace it once by hand

Round n digit rev
1 12345 5 5
2 1234 4 54
3 123 3 543
4 12 2 5432
5 1 1 54321
6 0 — stop

Doing this once makes the pattern stick forever.


Program 7 · Prime number check

How the logic works

A number is prime if nothing divides it evenly (except 1 and itself).

The trick: you only need to check up to the square root. If a factor bigger than √n existed, its partner would be smaller than √n — and you'd have found that already.

Code

public class Prime {
    public static void main(String[] args) {

        int n = 29;
        boolean isPrime = true;

        if (n <= 1) {
            isPrime = false;
        } else {
            for (int i = 2; i <= Math.sqrt(n); i++) {
                if (n % i == 0) {
                    isPrime = false;
                    break;                 // no need to keep looking
                }
            }
        }

        System.out.println(n + " is " + (isPrime ? "prime" : "not prime"));

        // print all primes up to 30
        System.out.print("Primes up to 30: ");
        for (int i = 2; i <= 30; i++) {
            boolean p = true;
            for (int j = 2; j <= Math.sqrt(i); j++)
                if (i % j == 0) { p = false; break; }
            if (p) System.out.print(i + " ");
        }
        System.out.println();
    }
}

Output

29 is prime
Primes up to 30: 2 3 5 7 11 13 17 19 23 29

Exam tip

Use Math.sqrt(n) as the limit, not n. It's a real optimisation and examiners give credit for it.


Program 8 · Fibonacci sequence

How the logic works

Each number is the sum of the two before it. Keep two variables and shuffle them along.

Code

public class Fibonacci {
    public static void main(String[] args) {

        int count = 10;
        int a = 0, b = 1;

        System.out.print("Fibonacci: ");
        for (int i = 1; i <= count; i++) {
            System.out.print(a + " ");
            int next = a + b;      // the new number
            a = b;                 // slide the window forward
            b = next;
        }
        System.out.println();
    }
}

Output

Fibonacci: 0 1 1 2 3 5 8 13 21 34

Program 9 · Even or odd

public class EvenOdd {
    public static void main(String[] args) {
        int n = 7;

        if (n % 2 == 0) System.out.println(n + " is Even");
        else            System.out.println(n + " is Odd");

        // same thing using the ternary operator
        System.out.println(n + " is " + ((n % 2 == 0) ? "Even" : "Odd"));
    }
}
7 is Odd
7 is Odd

Program 10 · Roots of a quadratic equation

How the logic works

Use the discriminant d = b² − 4ac.

Code

public class Quadratic {
    public static void main(String[] args) {

        double a = 1, b = -5, c = 6;        // x² - 5x + 6 = 0
        double d = b * b - 4 * a * c;

        System.out.println("Discriminant = " + d);

        if (d > 0) {
            double r1 = (-b + Math.sqrt(d)) / (2 * a);
            double r2 = (-b - Math.sqrt(d)) / (2 * a);
            System.out.println("Roots: " + r1 + " and " + r2);
        } else if (d == 0) {
            double r = -b / (2 * a);
            System.out.println("Repeated root: " + r);
        } else {
            double real = -b / (2 * a);
            double imag = Math.sqrt(-d) / (2 * a);
            System.out.println("Complex: " + real + " ± " + imag + "i");
        }
    }
}

Output

Discriminant = 1.0
Roots: 3.0 and 2.0

Program 11 · Largest of three numbers (nested if-else)

public class LargestThree {
    public static void main(String[] args) {

        int a = 25, b = 47, c = 19;

        if (a >= b) {
            if (a >= c) System.out.println("Largest = " + a);
            else        System.out.println("Largest = " + c);
        } else {
            if (b >= c) System.out.println("Largest = " + b);
            else        System.out.println("Largest = " + c);
        }
    }
}
Largest = 47

Program 12 · Weekday using switch

public class Weekday {
    public static void main(String[] args) {

        int day = 3;

        switch (day) {
            case 1: System.out.println("Monday");    break;
            case 2: System.out.println("Tuesday");   break;
            case 3: System.out.println("Wednesday"); break;
            case 4: System.out.println("Thursday");  break;
            case 5: System.out.println("Friday");    break;
            case 6:
            case 7: System.out.println("Weekend");   break;
            default: System.out.println("Invalid day");
        }
    }
}
Wednesday

Note how case 6: falls through to case 7: — both print "Weekend". Mention this in your answer; fall-through is a favourite exam point.


Program 13 · Constructor overloading 🔥

What it does

One class, several ways to build it.

How the logic works

Write the full constructor first, then make the simpler ones call it with this(...). That's called constructor chaining — one real implementation, several doorways.

Code

class Box {
    double width, height, depth;

    // the real one - does the actual work
    Box(double width, double height, double depth) {
        this.width  = width;
        this.height = height;
        this.depth  = depth;
    }

    // one input -> a perfect cube
    Box(double side) {
        this(side, side, side);          // calls the 3-arg constructor
    }

    // no input -> a 1x1x1 box
    Box() {
        this(1, 1, 1);
    }

    double volume() {
        return width * height * depth;
    }
}

public class ConstructorDemo {
    public static void main(String[] args) {
        Box b1 = new Box();
        Box b2 = new Box(5);
        Box b3 = new Box(2, 3, 4);

        System.out.println("b1 volume = " + b1.volume());   // 1.0
        System.out.println("b2 volume = " + b2.volume());   // 125.0
        System.out.println("b3 volume = " + b3.volume());   // 24.0
    }
}

Output

b1 volume = 1.0
b2 volume = 125.0
b3 volume = 24.0

Exam tip

this(...) must be the first line of the constructor. Nothing can come before it.


Program 14 · All inheritance types in one file

How the logic works

Four different shapes of "parent and child". Multiple and hybrid can only be done with interfaces.

Code

// ---------- 1. SINGLE ----------
class Vehicle { void start() { System.out.println("Vehicle starts"); } }
class Bike extends Vehicle { void ride() { System.out.println("Bike rides"); } }

// ---------- 2. MULTILEVEL ----------
class Animal { void eat() { System.out.println("Animal eats"); } }
class Mammal extends Animal { void walk() { System.out.println("Mammal walks"); } }
class Human extends Mammal { void speak() { System.out.println("Human speaks"); } }

// ---------- 3. HIERARCHICAL ----------
class Shape { void draw() { System.out.println("Shape drawn"); } }
class Circle extends Shape { void area() { System.out.println("Circle area"); } }
class Rect extends Shape { void area() { System.out.println("Rect area"); } }

// ---------- 4 + 5. MULTIPLE / HYBRID (interfaces only) ----------
interface Flyable { void fly(); }
interface Swimmable { void swim(); }

class Duck extends Animal implements Flyable, Swimmable {
    public void fly()  { System.out.println("Duck flies"); }
    public void swim() { System.out.println("Duck swims"); }
}

public class InheritanceDemo {
    public static void main(String[] args) {

        System.out.println("--- Single ---");
        Bike b = new Bike(); b.start(); b.ride();

        System.out.println("\n--- Multilevel ---");
        Human h = new Human(); h.eat(); h.walk(); h.speak();

        System.out.println("\n--- Hierarchical ---");
        Circle c = new Circle(); c.draw(); c.area();

        System.out.println("\n--- Hybrid (class + 2 interfaces) ---");
        Duck d = new Duck(); d.eat(); d.fly(); d.swim();
    }
}

Output

--- Single ---
Vehicle starts
Bike rides

--- Multilevel ---
Animal eats
Mammal walks
Human speaks

--- Hierarchical ---
Shape drawn
Circle area

--- Hybrid (class + 2 interfaces) ---
Animal eats
Duck flies
Duck swims

Program 15 · this and super

How the logic works

this = this object. super = the parent. Useful when a parameter has the same name as a field, and when a child needs the parent's version of something.

Code

class Person {
    String name;

    Person(String name) {
        this.name = name;                     // 'this' picks the field, not the parameter
        System.out.println("Person created: " + name);
    }

    void show() { System.out.println("Person: " + name); }
}

class Employee extends Person {
    int empId;

    Employee(String name, int empId) {
        super(name);                          // build the parent part FIRST
        this.empId = empId;
        System.out.println("Employee created: " + empId);
    }

    @Override
    void show() {
        super.show();                         // run the parent's version too
        System.out.println("Employee id: " + empId);
    }
}

public class ThisSuperDemo {
    public static void main(String[] args) {
        Employee e = new Employee("Riya", 501);
        System.out.println();
        e.show();
    }
}

Output

Person created: Riya
Employee created: 501

Person: Riya
Employee id: 501

Notice the order

The parent constructor finishes first. That's always true in Java.


Program 16 · Method overloading and overriding together

// ---------- OVERLOADING: same class, different inputs ----------
class Calculator {
    int add(int a, int b)          { return a + b; }
    int add(int a, int b, int c)   { return a + b + c; }
    double add(double a, double b) { return a + b; }
}

// ---------- OVERRIDING: child replaces parent ----------
class Animal {
    void sound() { System.out.println("Some animal sound"); }
}
class Dog extends Animal {
    @Override
    void sound() { System.out.println("Dog barks"); }
}
class Cat extends Animal {
    @Override
    void sound() { System.out.println("Cat meows"); }
}

public class PolymorphismDemo {
    public static void main(String[] args) {

        System.out.println("--- Overloading (decided at compile time) ---");
        Calculator c = new Calculator();
        System.out.println(c.add(10, 20));
        System.out.println(c.add(10, 20, 30));
        System.out.println(c.add(2.5, 3.5));

        System.out.println("\n--- Overriding (decided at run time) ---");
        Animal[] zoo = { new Dog(), new Cat(), new Animal() };
        for (Animal a : zoo) {
            a.sound();          // Java picks the right one automatically
        }
    }
}

Output

--- Overloading (decided at compile time) ---
30
60
6.0

--- Overriding (decided at run time) ---
Dog barks
Cat meows
Some animal sound

Program 17 · Abstraction with abstract class + interface

abstract class Shape {
    abstract double area();

    void describe() {
        System.out.printf("A %s with area %.2f%n",
                          getClass().getSimpleName(), area());
    }
}

class Circle extends Shape {
    double r;
    Circle(double r) { this.r = r; }
    double area() { return Math.PI * r * r; }
}

interface Drawable {
    void draw();
}

class Rectangle extends Shape implements Drawable {
    double w, h;
    Rectangle(double w, double h) { this.w = w; this.h = h; }
    double area() { return w * h; }
    public void draw() { System.out.println("Drawing a rectangle"); }
}

public class AbstractionDemo {
    public static void main(String[] args) {
        Circle c = new Circle(7);
        Rectangle r = new Rectangle(10, 5);

        c.describe();
        r.describe();
        r.draw();
    }
}

Output

A Circle with area 153.94
A Rectangle with area 50.00
Drawing a rectangle

Program 18 · Multiple inheritance via interfaces 🔥

This is Assignment 2 Q1, word for word.

interface Shape   { double area(); }
interface Bounded { double perimeter(); }

class Circle implements Shape, Bounded {
    double r;
    Circle(double r) { this.r = r; }
    public double area()      { return Math.PI * r * r; }
    public double perimeter() { return 2 * Math.PI * r; }
}

class Square implements Shape, Bounded {
    double side;
    Square(double side) { this.side = side; }
    public double area()      { return side * side; }
    public double perimeter() { return 4 * side; }
}

public class InterfaceDemo {
    public static void main(String[] args) {

        Circle c = new Circle(7);
        Square s = new Square(5);

        System.out.printf("Circle: area = %.2f, perimeter = %.2f%n",
                          c.area(), c.perimeter());
        System.out.printf("Square: area = %.2f, perimeter = %.2f%n",
                          s.area(), s.perimeter());
    }
}

Output

Circle: area = 153.94, perimeter = 43.98
Square: area = 25.00, perimeter = 20.00

Program 19 · Custom exception 🔥

The sample paper asks for this by name.

How the logic works

Three steps, always the same:

  1. Make a class that extends Exception
  2. Give it super(message) in the constructor
  3. throw it when the rule breaks, and declare throws on the method

Code

class InvalidAgeException extends Exception {          // 1
    InvalidAgeException(String message) {
        super(message);                                // 2
    }
}

public class CustomExceptionDemo {

    static void checkAge(int age) throws InvalidAgeException {   // 3
        if (age < 18) {
            throw new InvalidAgeException("Age " + age + " is below 18");
        }
        System.out.println("Age " + age + " accepted");
    }

    public static void main(String[] args) {

        int[] ages = {25, 15, 18, 10};

        for (int age : ages) {
            try {
                checkAge(age);
            } catch (InvalidAgeException e) {
                System.out.println("Rejected: " + e.getMessage());
            }
        }
    }
}

Output

Age 25 accepted
Rejected: Age 15 is below 18
Age 18 accepted
Rejected: Age 10 is below 18

Exam tip

Three things are checked: extends Exception, super(message), and throws on the method. Miss one, lose a mark.


Program 20 · Two threads with a shared counter 🔥

Assignment 3 Q3, and in the sample paper.

How the logic works

Two threads each add 1 to the same counter 100,000 times. Without protection they overwrite each other. synchronized makes them take turns.

Code

class Counter {
    private int count = 0;

    public synchronized void increment() {   // only one thread at a time
        count++;
    }
    public int getCount() { return count; }
}

class Worker implements Runnable {
    private final Counter counter;
    Worker(Counter c) { this.counter = c; }

    public void run() {
        for (int i = 0; i < 100000; i++) {
            counter.increment();
        }
    }
}

public class SyncDemo {
    public static void main(String[] args) throws InterruptedException {

        Counter counter = new Counter();

        Thread t1 = new Thread(new Worker(counter), "Thread-1");
        Thread t2 = new Thread(new Worker(counter), "Thread-2");

        t1.start();
        t2.start();

        t1.join();          // wait for t1 to finish
        t2.join();          // wait for t2 to finish

        System.out.println("Expected: " + 200000);
        System.out.println("Actual  : " + counter.getCount());
    }
}

Output

Expected: 200000
Actual  : 200000

Now delete the word synchronized and run it again

Expected: 200000
Actual  : 174823

A different number every time. That is a race condition.

Write both outputs in your answer. It's worth more than any explanation.


Program 21 · ArrayList operations

import java.util.*;

public class ArrayListDemo {
    public static void main(String[] args) {

        ArrayList<String> list = new ArrayList<>();

        list.add("Java");                    // add at end
        list.add("Python");
        list.add(1, "C++");                  // insert at position 1
        System.out.println("after add   : " + list);

        System.out.println("get(0)      : " + list.get(0));
        System.out.println("size        : " + list.size());

        list.set(0, "JavaScript");           // replace
        System.out.println("after set   : " + list);

        list.remove("Python");
        System.out.println("after remove: " + list);

        System.out.println("contains C++ : " + list.contains("C++"));

        System.out.print("for-each    : ");
        for (String s : list) System.out.print(s + " ");
        System.out.println();
    }
}

Output

after add   : [Java, C++, Python]
get(0)      : Java
size        : 3
after set   : [JavaScript, C++, Python]
after remove: [JavaScript, C++]
contains C++ : true
for-each    : JavaScript C++ 

Program 22 · HashSet vs TreeSet, side by side

import java.util.*;

public class SetDemo {
    public static void main(String[] args) {

        int[] data = {5, 3, 8, 3, 1, 5, 9, 1};

        HashSet<Integer> hash = new HashSet<>();
        TreeSet<Integer> tree = new TreeSet<>();

        for (int n : data) { hash.add(n); tree.add(n); }

        System.out.println("Original : " + Arrays.toString(data));
        System.out.println("HashSet  : " + hash + "   (no order)");
        System.out.println("TreeSet  : " + tree + "   (sorted)");
        System.out.println("first    : " + tree.first());
        System.out.println("last     : " + tree.last());
    }
}

Output

Original : [5, 3, 8, 3, 1, 5, 9, 1]
HashSet  : [1, 3, 5, 8, 9]   (no order)
TreeSet  : [1, 3, 5, 8, 9]   (sorted)
first    : 1
last     : 9

Program 23 · HashMap — student records

import java.util.*;

public class HashMapDemo {
    public static void main(String[] args) {

        HashMap<Integer, String> students = new HashMap<>();

        students.put(101, "Aarav");
        students.put(102, "Diya");
        students.put(103, "Kabir");

        System.out.println("All      : " + students);
        System.out.println("get(102) : " + students.get(102));
        System.out.println("get(999) : " + students.get(999));
        System.out.println("size     : " + students.size());

        students.put(102, "Diya Patel");     // same key -> overwritten
        System.out.println("updated  : " + students.get(102));

        System.out.println("\n--- entrySet ---");
        for (Map.Entry<Integer, String> e : students.entrySet()) {
            System.out.println("Roll " + e.getKey() + " -> " + e.getValue());
        }
    }
}

Output

All      : {101=Aarav, 102=Diya, 103=Kabir}
get(102) : Diya
get(999) : null
size     : 3
updated  : Diya Patel

--- entrySet ---
Roll 101 -> Aarav
Roll 102 -> Diya Patel
Roll 103 -> Kabir

Program 24 · Write and read a file

import java.io.*;

public class FileDemo {
    public static void main(String[] args) {

        String path = "demo.txt";
        String text = "Hello students.\nWelcome to Java file handling.";

        // WRITE
        try (FileOutputStream fos = new FileOutputStream(path)) {
            fos.write(text.getBytes());
            System.out.println("Written.");
        } catch (IOException e) {
            System.out.println("Write error: " + e.getMessage());
        }

        // READ
        try (FileInputStream fis = new FileInputStream(path)) {
            int ch;
            StringBuilder sb = new StringBuilder();
            while ((ch = fis.read()) != -1) {
                sb.append((char) ch);
            }
            System.out.println(sb);
        } catch (IOException e) {
            System.out.println("Read error: " + e.getMessage());
        }
    }
}

Output

Written.
Hello students.
Welcome to Java file handling.

Program 25 · Serialization

import java.io.*;

class Student implements Serializable {
    private static final long serialVersionUID = 1L;

    int rollNo;
    String name;
    transient String password;      // this one is NOT saved

    Student(int rollNo, String name, String password) {
        this.rollNo = rollNo;
        this.name = name;
        this.password = password;
    }
}

public class SerializationDemo {
    public static void main(String[] args) {

        Student s = new Student(101, "Aarav", "secret");

        try (ObjectOutputStream out =
                 new ObjectOutputStream(new FileOutputStream("student.ser"))) {
            out.writeObject(s);
            System.out.println("Saved:  " + s.rollNo + " " + s.name + " " + s.password);
        } catch (IOException e) { System.out.println(e.getMessage()); }

        try (ObjectInputStream in =
                 new ObjectInputStream(new FileInputStream("student.ser"))) {
            Student d = (Student) in.readObject();
            System.out.println("Loaded: " + d.rollNo + " " + d.name + " " + d.password);
        } catch (IOException | ClassNotFoundException e) { System.out.println(e.getMessage()); }
    }
}

Output

Saved:  101 Aarav secret
Loaded: 101 Aarav null

null is the point. transient fields don't get saved.


Program 26 · Stream API — filter and map

import java.util.*;
import java.util.stream.*;

public class StreamDemo {
    public static void main(String[] args) {

        List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

        List<Integer> evenSquares = numbers.stream()
                .filter(n -> n % 2 == 0)
                .map(n -> n * n)
                .collect(Collectors.toList());

        System.out.println("Even squares : " + evenSquares);
        System.out.println("Count        : " + numbers.stream().filter(n -> n % 2 == 0).count());
        System.out.println("Sum          : " + numbers.stream().reduce(0, Integer::sum));
    }
}

Output

Even squares : [4, 16, 36, 64, 100]
Count        : 5
Sum          : 55

Program 27 · Bubble sort

How the logic works

Compare each pair of neighbours. If they're in the wrong order, swap them. Repeat until nothing swaps — then it's sorted.

public class BubbleSort {
    public static void main(String[] args) {

        int[] a = {64, 34, 25, 12, 22, 11, 90};
        System.out.println("Before: " + java.util.Arrays.toString(a));

        for (int i = 0; i < a.length - 1; i++) {
            boolean swapped = false;
            for (int j = 0; j < a.length - 1 - i; j++) {
                if (a[j] > a[j + 1]) {
                    int temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                    swapped = true;
                }
            }
            if (!swapped) break;      // nothing moved, so we're done early
        }

        System.out.println("After : " + java.util.Arrays.toString(a));
    }
}
Before: [64, 34, 25, 12, 22, 11, 90]
After : [11, 12, 22, 25, 34, 64, 90]

Program 28 · Palindrome

public class Palindrome {
    public static void main(String[] args) {

        // ---- a word ----
        String s = "madam";
        String rev = new StringBuilder(s).reverse().toString();
        System.out.println(s + " -> " + (s.equals(rev) ? "palindrome" : "not"));

        // ---- a number ----
        int n = 12321, original = n, r = 0;
        while (n != 0) {
            r = r * 10 + n % 10;
            n = n / 10;
        }
        System.out.println(original + " -> " + (original == r ? "palindrome" : "not"));

        // ---- a non-palindrome, for contrast ----
        System.out.println("java -> " +
            new StringBuilder("java").reverse().toString().equals("java"));
    }
}

Output

madam -> palindrome
12321 -> palindrome
java -> false

Program 29 · Array stats — sum, average, min, max

public class ArrayStats {
    public static void main(String[] args) {

        int[] a = {12, 45, 7, 89, 23, 56};

        int sum = 0, min = a[0], max = a[0];

        for (int n : a) {
            sum += n;
            if (n < min) min = n;
            if (n > max) max = n;
        }

        double avg = (double) sum / a.length;    // the cast matters

        System.out.println("Sum     : " + sum);
        System.out.println("Average : " + avg);
        System.out.println("Min     : " + min);
        System.out.println("Max     : " + max);
    }
}

Output

Sum     : 232
Average : 38.666666666666664
Min     : 7
Max     : 89

The cast that earns the mark

(double) sum / a.length gives 38.67. Without the cast you get 38, because dividing two ints throws away the decimals.


Program 30 · Generic class and swap

class Box<T> {
    private T value;
    Box(T value) { this.value = value; }
    T get() { return value; }
    void show() {
        System.out.println(value + " (" + value.getClass().getSimpleName() + ")");
    }
}

class Utils {
    static <T> void swap(T[] arr, int i, int j) {
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

public class GenericsDemo {
    public static void main(String[] args) {

        new Box<String>("Parul").show();
        new Box<Integer>(2026).show();
        new Box<Double>(9.81).show();

        String[] names = {"A", "B", "C", "D"};
        System.out.println("Before: " + java.util.Arrays.toString(names));
        Utils.swap(names, 0, 3);
        System.out.println("After : " + java.util.Arrays.toString(names));
    }
}

Output

Parul (String)
2026 (Integer)
9.81 (Double)
Before: [A, B, C, D]
After : [D, B, C, A]

Output-prediction drills

The objective section loves these. Predict first, then check.

System.out.println(10 + 20 + "Java" + 10 + 20);   // 30Java1020
System.out.println(10 / 3);                        // 3
System.out.println(10 / 3.0);                      // 3.3333333333333335
System.out.println(10 % 3);                        // 1
System.out.println(5 & 3);                         // 1
System.out.println(5 | 3);                         // 7
System.out.println(5 ^ 3);                         // 6
System.out.println(~5);                            // -6
System.out.println('A' + 1);                       // 66
System.out.println((char) ('A' + 1));              // B
System.out.println((int) 9.99);                    // 9   (truncates!)

int a = 5; System.out.println(a++);                // 5
int b = 5; System.out.println(++b);                // 6

System.out.println("Java" == "Java");              // true
System.out.println("Java" == new String("Java"));  // false
System.out.println("Java".equals(new String("Java"))); // true
System.out.println(0.1 + 0.2 == 0.3);              // false

The complete table

Expression Output Why
10 + 20 + "Java" + 10 + 20 30Java1020 Numbers add first, then everything becomes text
10 / 3 3 Integer division drops decimals
10 / 3.0 3.3333333333333335 One decimal makes the answer decimal
10 % 3 1 Remainder
(int) 9.99 9 Truncates, does not round
5 & 3 / 5 \| 3 / 5 ^ 3 1 / 7 / 6 Bitwise operations
~5 -6 Bitwise NOT
'A' + 1 66 char becomes a number
(char)('A' + 1) B Number back to a letter
"Java" == "Java" true Same object in the string pool
"Java" == new String("Java") false Two different objects
.equals(...) on both true Same letters
0.1 + 0.2 == 0.3 false Floating point is imprecise

If you freeze in the exam

You're stuck on a program worth 5 marks. Do this:

  1. Write the skeleton. public class X { public static void main(String[] args) { } } — 1 mark for structure.
  2. Declare the input. int[] a = {12, 45, 7, 89};
  3. Write the loop. A for loop that visits each element.
  4. Print something sensible at the end, even if the logic is rough.

Rough but structured scores. Blank scores nothing.