Skip to main content
  1. Resources/
  2. Study Materials/
  3. Information & Communication Technology Engineering/
  4. ICT Semester 4/
  5. Java Programming (4343203)/

17 mins· ·
Milav Dabgar
Author
Milav Dabgar
Experienced lecturer in the electrical and electronic manufacturing industry. Skilled in Embedded Systems, Image Processing, Data Science, MATLAB, Python, STM32. Strong education professional with a Master’s degree in Communication Systems Engineering from L.D. College of Engineering - Ahmedabad.
Java Programming Examples - Complete Applications

Java Programming Examples

Complete Applications & Practical Implementation

Chapter 13: Real-World Java Programming
Comprehensive examples integrating all Java concepts

Student Management System

Core Classes Design


// Student.java
public class Student {
    private String id;
    private String name;
    private String email;
    private List<Course> courses;
    private Map<String, Grade> grades;
    
    public Student(String id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.courses = new ArrayList<>();
        this.grades = new HashMap<>();
    }
    
    public void enrollInCourse(Course course) {
        if (!courses.contains(course)) {
            courses.add(course);
            course.addStudent(this);
        }
    }
    
    public void addGrade(String courseId, Grade grade) {
        grades.put(courseId, grade);
    }
    
    public double calculateGPA() {
        if (grades.isEmpty()) return 0.0;
        
        double totalPoints = 0;
        int totalCredits = 0;
        
        for (Map.Entry<String, Grade> entry : grades.entrySet()) {
            Grade grade = entry.getValue();
            totalPoints += grade.getPoints() * grade.getCredits();
            totalCredits += grade.getCredits();
        }
        
        return totalCredits > 0 ? totalPoints / totalCredits : 0.0;
    }
    
    // Getters and setters...
}
                        

Course & Grade Classes


// Course.java
public class Course {
    private String courseId;
    private String title;
    private int credits;
    private String instructor;
    private List<Student> enrolledStudents;
    private int maxCapacity;
    
    public Course(String courseId, String title, 
                  int credits, String instructor, int maxCapacity) {
        this.courseId = courseId;
        this.title = title;
        this.credits = credits;
        this.instructor = instructor;
        this.maxCapacity = maxCapacity;
        this.enrolledStudents = new ArrayList<>();
    }
    
    public boolean addStudent(Student student) {
        if (enrolledStudents.size() < maxCapacity && 
            !enrolledStudents.contains(student)) {
            enrolledStudents.add(student);
            return true;
        }
        return false;
    }
    
    public List<Student> getEnrolledStudents() {
        return new ArrayList<>(enrolledStudents);
    }
}

// Grade.java
public class Grade {
    private double points; // 4.0 scale
    private int credits;
    private String letterGrade;
    
    public Grade(double points, int credits) {
        this.points = points;
        this.credits = credits;
        this.letterGrade = calculateLetterGrade(points);
    }
    
    private String calculateLetterGrade(double points) {
        if (points >= 3.7) return "A";
        else if (points >= 3.3) return "A-";
        else if (points >= 3.0) return "B+";
        else if (points >= 2.7) return "B";
        else if (points >= 2.3) return "B-";
        else if (points >= 2.0) return "C+";
        else if (points >= 1.7) return "C";
        else if (points >= 1.3) return "C-";
        else if (points >= 1.0) return "D";
        else return "F";
    }
}
                        

StudentManager Implementation


// StudentManager.java
import java.util.*;
import java.util.stream.Collectors;

public class StudentManager {
    private Map<String, Student> students;
    private Map<String, Course> courses;
    private static final String DATA_FILE = "students.dat";
    
    public StudentManager() {
        students = new HashMap<>();
        courses = new HashMap<>();
        loadData();
    }
    
    public void addStudent(Student student) {
        students.put(student.getId(), student);
        saveData();
    }
    
    public void addCourse(Course course) {
        courses.put(course.getCourseId(), course);
        saveData();
    }
    
    public boolean enrollStudent(String studentId, String courseId) {
        Student student = students.get(studentId);
        Course course = courses.get(courseId);
        
        if (student != null && course != null) {
            student.enrollInCourse(course);
            saveData();
            return true;
        }
        return false;
    }
    
    public void recordGrade(String studentId, String courseId, double points, int credits) {
        Student student = students.get(studentId);
        if (student != null) {
            Grade grade = new Grade(points, credits);
            student.addGrade(courseId, grade);
            saveData();
        }
    }
    
    public List<Student> getTopStudents(int count) {
        return students.values().stream()
                .sorted((s1, s2) -> Double.compare(s2.calculateGPA(), s1.calculateGPA()))
                .limit(count)
                .collect(Collectors.toList());
    }
    
    public List<Student> searchStudents(String searchTerm) {
        return students.values().stream()
                .filter(s -> s.getName().toLowerCase().contains(searchTerm.toLowerCase()) ||
                           s.getEmail().toLowerCase().contains(searchTerm.toLowerCase()))
                .collect(Collectors.toList());
    }
    
    public Map<String, Long> getCourseEnrollmentStats() {
        return courses.values().stream()
                .collect(Collectors.toMap(
                    Course::getTitle,
                    course -> (long) course.getEnrolledStudents().size()
                ));
    }
    
    // File I/O methods
    private void saveData() {
        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream(DATA_FILE))) {
            oos.writeObject(students);
            oos.writeObject(courses);
        } catch (IOException e) {
            System.err.println("Error saving data: " + e.getMessage());
        }
    }
    
    @SuppressWarnings("unchecked")
    private void loadData() {
        try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream(DATA_FILE))) {
            students = (Map<String, Student>) ois.readObject();
            courses = (Map<String, Course>) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            // File doesn't exist or is corrupted, start fresh
            students = new HashMap<>();
            courses = new HashMap<>();
        }
    }
}

Banking System with Transactions

Account Hierarchy


// Account.java (Abstract Base Class)
public abstract class Account {
    protected String accountNumber;
    protected String holderName;
    protected double balance;
    protected List<Transaction> transactions;
    protected final Object lock = new Object();
    
    public Account(String accountNumber, String holderName, 
                   double initialBalance) {
        this.accountNumber = accountNumber;
        this.holderName = holderName;
        this.balance = initialBalance;
        this.transactions = new ArrayList<>();
    }
    
    public synchronized boolean deposit(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Deposit amount must be positive");
        }
        
        balance += amount;
        Transaction transaction = new Transaction(
            TransactionType.DEPOSIT, amount, balance
        );
        transactions.add(transaction);
        return true;
    }
    
    public synchronized boolean withdraw(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Withdrawal amount must be positive");
        }
        
        if (canWithdraw(amount)) {
            balance -= amount;
            Transaction transaction = new Transaction(
                TransactionType.WITHDRAWAL, amount, balance
            );
            transactions.add(transaction);
            return true;
        }
        return false;
    }
    
    protected abstract boolean canWithdraw(double amount);
    
    public synchronized double getBalance() {
        return balance;
    }
    
    public List<Transaction> getTransactionHistory() {
        synchronized(lock) {
            return new ArrayList<>(transactions);
        }
    }
}
                        

Specific Account Types


// SavingsAccount.java
public class SavingsAccount extends Account {
    private double interestRate;
    private int withdrawalCount;
    private static final int MAX_WITHDRAWALS = 6;
    
    public SavingsAccount(String accountNumber, String holderName, 
                         double initialBalance, double interestRate) {
        super(accountNumber, holderName, initialBalance);
        this.interestRate = interestRate;
        this.withdrawalCount = 0;
    }
    
    @Override
    protected boolean canWithdraw(double amount) {
        return balance >= amount && withdrawalCount < MAX_WITHDRAWALS;
    }
    
    @Override
    public synchronized boolean withdraw(double amount) {
        if (super.withdraw(amount)) {
            withdrawalCount++;
            return true;
        }
        return false;
    }
    
    public void applyMonthlyInterest() {
        synchronized(lock) {
            double interest = balance * (interestRate / 12);
            balance += interest;
            withdrawalCount = 0; // Reset monthly withdrawal count
        }
    }
}

// CheckingAccount.java
public class CheckingAccount extends Account {
    private double overdraftLimit;
    
    public CheckingAccount(String accountNumber, String holderName, 
                          double initialBalance, double overdraftLimit) {
        super(accountNumber, holderName, initialBalance);
        this.overdraftLimit = overdraftLimit;
    }
    
    @Override
    protected boolean canWithdraw(double amount) {
        return (balance + overdraftLimit) >= amount;
    }
}

// Transaction.java
public class Transaction {
    private final String transactionId;
    private final TransactionType type;
    private final double amount;
    private final double balanceAfter;
    private final LocalDateTime timestamp;
    
    public Transaction(TransactionType type, double amount, double balanceAfter) {
        this.transactionId = UUID.randomUUID().toString();
        this.type = type;
        this.amount = amount;
        this.balanceAfter = balanceAfter;
        this.timestamp = LocalDateTime.now();
    }
    
    // Getters...
}

enum TransactionType {
    DEPOSIT, WITHDRAWAL, TRANSFER_IN, TRANSFER_OUT, INTEREST
}
                        

Bank Management System


// Bank.java
public class Bank {
    private Map<String, Account> accounts;
    private ExecutorService transactionExecutor;
    private final ReentrantLock bankLock = new ReentrantLock();
    
    public Bank() {
        accounts = new ConcurrentHashMap<>();
        transactionExecutor = Executors.newFixedThreadPool(10);
    }
    
    public void createSavingsAccount(String accountNumber, String holderName, 
                                   double initialBalance, double interestRate) {
        Account account = new SavingsAccount(accountNumber, holderName, 
                                           initialBalance, interestRate);
        accounts.put(accountNumber, account);
    }
    
    public void createCheckingAccount(String accountNumber, String holderName, 
                                    double initialBalance, double overdraftLimit) {
        Account account = new CheckingAccount(accountNumber, holderName, 
                                            initialBalance, overdraftLimit);
        accounts.put(accountNumber, account);
    }
    
    public CompletableFuture<Boolean> transfer(String fromAccount, String toAccount, double amount) {
        return CompletableFuture.supplyAsync(() -> {
            Account from = accounts.get(fromAccount);
            Account to = accounts.get(toAccount);
            
            if (from == null || to == null) {
                throw new IllegalArgumentException("Invalid account number");
            }
            
            // Ensure consistent ordering to prevent deadlocks
            Account firstLock = fromAccount.compareTo(toAccount) < 0 ? from : to;
            Account secondLock = fromAccount.compareTo(toAccount) < 0 ? to : from;
            
            synchronized(firstLock) {
                synchronized(secondLock) {
                    if (from.getBalance() >= amount) {
                        from.withdraw(amount);
                        to.deposit(amount);
                        return true;
                    }
                }
            }
            return false;
        }, transactionExecutor);
    }
    
    public Account getAccount(String accountNumber) {
        return accounts.get(accountNumber);
    }
    
    public List<Account> getAllAccounts() {
        return new ArrayList<>(accounts.values());
    }
    
    public Map<String, Double> generateBalanceReport() {
        return accounts.entrySet().stream()
                .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> entry.getValue().getBalance()
                ));
    }
    
    public void applyMonthlyInterest() {
        accounts.values().parallelStream()
                .filter(account -> account instanceof SavingsAccount)
                .map(account -> (SavingsAccount) account)
                .forEach(SavingsAccount::applyMonthlyInterest);
    }
    
    public void shutdown() {
        transactionExecutor.shutdown();
        try {
            if (!transactionExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
                transactionExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            transactionExecutor.shutdownNow();
        }
    }
}

E-commerce Order Processing System

Product & Inventory


// Product.java
public class Product implements Serializable {
    private String productId;
    private String name;
    private String description;
    private double price;
    private String category;
    private int stockQuantity;
    private Set<String> tags;
    
    public Product(String productId, String name, String description, 
                   double price, String category, int stockQuantity) {
        this.productId = productId;
        this.name = name;
        this.description = description;
        this.price = price;
        this.category = category;
        this.stockQuantity = stockQuantity;
        this.tags = new HashSet<>();
    }
    
    public synchronized boolean reserveStock(int quantity) {
        if (stockQuantity >= quantity) {
            stockQuantity -= quantity;
            return true;
        }
        return false;
    }
    
    public synchronized void restoreStock(int quantity) {
        stockQuantity += quantity;
    }
    
    public boolean isInStock() {
        return stockQuantity > 0;
    }
    
    // Getters and setters...
}

// ShoppingCart.java
public class ShoppingCart {
    private Map<String, CartItem> items;
    private String customerId;
    
    public ShoppingCart(String customerId) {
        this.customerId = customerId;
        this.items = new HashMap<>();
    }
    
    public void addItem(Product product, int quantity) {
        String productId = product.getProductId();
        
        if (items.containsKey(productId)) {
            CartItem existingItem = items.get(productId);
            existingItem.setQuantity(existingItem.getQuantity() + quantity);
        } else {
            items.put(productId, new CartItem(product, quantity));
        }
    }
    
    public void removeItem(String productId) {
        items.remove(productId);
    }
    
    public double calculateTotal() {
        return items.values().stream()
                .mapToDouble(item -> item.getProduct().getPrice() * item.getQuantity())
                .sum();
    }
    
    public Map<String, CartItem> getItems() {
        return new HashMap<>(items);
    }
    
    public void clear() {
        items.clear();
    }
}
                        

Order Processing


// Order.java
public class Order implements Serializable {
    private String orderId;
    private String customerId;
    private List<OrderItem> items;
    private OrderStatus status;
    private LocalDateTime orderDate;
    private double totalAmount;
    private String shippingAddress;
    
    public Order(String customerId, String shippingAddress) {
        this.orderId = generateOrderId();
        this.customerId = customerId;
        this.shippingAddress = shippingAddress;
        this.items = new ArrayList<>();
        this.status = OrderStatus.PENDING;
        this.orderDate = LocalDateTime.now();
        this.totalAmount = 0.0;
    }
    
    public void addItem(Product product, int quantity) {
        OrderItem item = new OrderItem(product, quantity, product.getPrice());
        items.add(item);
        calculateTotal();
    }
    
    private void calculateTotal() {
        totalAmount = items.stream()
                .mapToDouble(item -> item.getPrice() * item.getQuantity())
                .sum();
    }
    
    public void updateStatus(OrderStatus newStatus) {
        this.status = newStatus;
    }
    
    private String generateOrderId() {
        return "ORD-" + System.currentTimeMillis() + "-" + 
               String.format("%04d", new Random().nextInt(10000));
    }
    
    // Getters...
}

enum OrderStatus {
    PENDING, CONFIRMED, PROCESSING, SHIPPED, DELIVERED, CANCELLED
}

// OrderItem.java
public class OrderItem implements Serializable {
    private Product product;
    private int quantity;
    private double price; // Price at time of order
    
    public OrderItem(Product product, int quantity, double price) {
        this.product = product;
        this.quantity = quantity;
        this.price = price;
    }
    
    public double getSubtotal() {
        return price * quantity;
    }
    
    // Getters and setters...
}
                        

Order Processing Service


// OrderProcessor.java
public class OrderProcessor {
    private Map<String, Product> inventory;
    private Map<String, Order> orders;
    private Map<String, ShoppingCart> carts;
    private Queue<String> processingQueue;
    private ExecutorService orderProcessingPool;
    private final Object inventoryLock = new Object();
    
    public OrderProcessor() {
        inventory = new ConcurrentHashMap<>();
        orders = new ConcurrentHashMap<>();
        carts = new ConcurrentHashMap<>();
        processingQueue = new ConcurrentLinkedQueue<>();
        orderProcessingPool = Executors.newFixedThreadPool(5);
        
        // Start background order processing
        startOrderProcessing();
    }
    
    public void addProduct(Product product) {
        inventory.put(product.getProductId(), product);
    }
    
    public ShoppingCart getCart(String customerId) {
        return carts.computeIfAbsent(customerId, k -> new ShoppingCart(customerId));
    }
    
    public boolean addToCart(String customerId, String productId, int quantity) {
        Product product = inventory.get(productId);
        if (product == null || !product.isInStock()) {
            return false;
        }
        
        ShoppingCart cart = getCart(customerId);
        cart.addItem(product, quantity);
        return true;
    }
    
    public Order createOrder(String customerId, String shippingAddress) {
        ShoppingCart cart = carts.get(customerId);
        if (cart == null || cart.getItems().isEmpty()) {
            throw new IllegalStateException("Cart is empty");
        }
        
        Order order = new Order(customerId, shippingAddress);
        
        // Reserve inventory and create order items
        synchronized(inventoryLock) {
            for (CartItem cartItem : cart.getItems().values()) {
                Product product = cartItem.getProduct();
                int quantity = cartItem.getQuantity();
                
                if (!product.reserveStock(quantity)) {
                    // Restore any previously reserved stock
                    rollbackOrderReservations(order);
                    throw new InsufficientStockException(
                        "Insufficient stock for product: " + product.getName());
                }
                
                order.addItem(product, quantity);
            }
        }
        
        orders.put(order.getOrderId(), order);
        cart.clear();
        
        // Queue for processing
        processingQueue.offer(order.getOrderId());
        
        return order;
    }
    
    private void rollbackOrderReservations(Order order) {
        for (OrderItem item : order.getItems()) {
            item.getProduct().restoreStock(item.getQuantity());
        }
    }
    
    private void startOrderProcessing() {
        orderProcessingPool.submit(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    String orderId = processingQueue.poll();
                    if (orderId != null) {
                        processOrder(orderId);
                    }
                    Thread.sleep(1000); // Check every second
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
    }
    
    private void processOrder(String orderId) {
        Order order = orders.get(orderId);
        if (order != null && order.getStatus() == OrderStatus.PENDING) {
            try {
                // Simulate payment processing
                Thread.sleep(2000);
                order.updateStatus(OrderStatus.CONFIRMED);
                
                // Simulate order fulfillment
                Thread.sleep(3000);
                order.updateStatus(OrderStatus.PROCESSING);
                
                // Simulate shipping
                Thread.sleep(1000);
                order.updateStatus(OrderStatus.SHIPPED);
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    public List<Product> searchProducts(String searchTerm) {
        return inventory.values().stream()
                .filter(product -> 
                    product.getName().toLowerCase().contains(searchTerm.toLowerCase()) ||
                    product.getDescription().toLowerCase().contains(searchTerm.toLowerCase()) ||
                    product.getTags().stream().anyMatch(tag -> 
                        tag.toLowerCase().contains(searchTerm.toLowerCase())))
                .collect(Collectors.toList());
    }
    
    public List<Product> getProductsByCategory(String category) {
        return inventory.values().stream()
                .filter(product -> product.getCategory().equalsIgnoreCase(category))
                .collect(Collectors.toList());
    }
    
    public Map<String, Long> getOrderStatistics() {
        return orders.values().stream()
                .collect(Collectors.groupingBy(
                    order -> order.getStatus().toString(),
                    Collectors.counting()
                ));
    }
    
    public void shutdown() {
        orderProcessingPool.shutdown();
    }
}

class InsufficientStockException extends RuntimeException {
    public InsufficientStockException(String message) {
        super(message);
    }
}

Main Application Demonstrations

Student Management Demo


public class StudentManagementDemo {
    public static void main(String[] args) {
        StudentManager manager = new StudentManager();
        
        // Create courses
        Course javaCourse = new Course("CS101", "Java Programming", 
                                     3, "Dr. Smith", 30);
        Course dataStructures = new Course("CS201", "Data Structures", 
                                         4, "Dr. Johnson", 25);
        
        manager.addCourse(javaCourse);
        manager.addCourse(dataStructures);
        
        // Create students
        Student student1 = new Student("S001", "Alice Johnson", 
                                     "alice@email.com");
        Student student2 = new Student("S002", "Bob Smith", 
                                     "bob@email.com");
        Student student3 = new Student("S003", "Carol Davis", 
                                     "carol@email.com");
        
        manager.addStudent(student1);
        manager.addStudent(student2);
        manager.addStudent(student3);
        
        // Enroll students
        manager.enrollStudent("S001", "CS101");
        manager.enrollStudent("S001", "CS201");
        manager.enrollStudent("S002", "CS101");
        manager.enrollStudent("S003", "CS201");
        
        // Record grades
        manager.recordGrade("S001", "CS101", 3.7, 3); // A
        manager.recordGrade("S001", "CS201", 3.3, 4); // A-
        manager.recordGrade("S002", "CS101", 3.0, 3); // B+
        manager.recordGrade("S003", "CS201", 4.0, 4); // A
        
        // Display results
        System.out.println("Top Students:");
        List<Student> topStudents = manager.getTopStudents(3);
        for (Student student : topStudents) {
            System.out.printf("%s - GPA: %.2f%n", 
                student.getName(), student.calculateGPA());
        }
        
        // Course enrollment statistics
        Map<String, Long> stats = manager.getCourseEnrollmentStats();
        System.out.println("\nCourse Enrollment:");
        stats.forEach((course, count) -> 
            System.out.printf("%s: %d students%n", course, count));
    }
}
                        

Banking System Demo


public class BankingDemo {
    public static void main(String[] args) throws Exception {
        Bank bank = new Bank();
        
        // Create accounts
        bank.createSavingsAccount("SAV001", "Alice Smith", 
                                 1000.0, 0.02);
        bank.createCheckingAccount("CHK001", "Bob Johnson", 
                                  500.0, 200.0);
        bank.createSavingsAccount("SAV002", "Carol Davis", 
                                 2000.0, 0.02);
        
        // Perform transactions
        Account aliceAccount = bank.getAccount("SAV001");
        Account bobAccount = bank.getAccount("CHK001");
        
        // Deposits and withdrawals
        aliceAccount.deposit(500.0);
        bobAccount.withdraw(100.0);
        
        System.out.println("Initial Balances:");
        System.out.printf("Alice: $%.2f%n", aliceAccount.getBalance());
        System.out.printf("Bob: $%.2f%n", bobAccount.getBalance());
        
        // Transfer money between accounts
        CompletableFuture<Boolean> transferResult = 
            bank.transfer("SAV001", "CHK001", 300.0);
        
        boolean success = transferResult.get();
        System.out.println("\nTransfer successful: " + success);
        
        System.out.println("After Transfer:");
        System.out.printf("Alice: $%.2f%n", aliceAccount.getBalance());
        System.out.printf("Bob: $%.2f%n", bobAccount.getBalance());
        
        // Generate balance report
        Map<String, Double> balanceReport = bank.generateBalanceReport();
        System.out.println("\nBank Balance Report:");
        balanceReport.forEach((account, balance) -> 
            System.out.printf("%s: $%.2f%n", account, balance));
        
        // Transaction history
        System.out.println("\nAlice's Transaction History:");
        aliceAccount.getTransactionHistory().forEach(transaction -> 
            System.out.printf("%s: $%.2f (Balance: $%.2f) at %s%n",
                transaction.getType(), transaction.getAmount(),
                transaction.getBalanceAfter(), transaction.getTimestamp()));
        
        bank.shutdown();
    }
}
                        

E-commerce System Demo


public class EcommerceDemo {
    public static void main(String[] args) throws Exception {
        OrderProcessor processor = new OrderProcessor();
        
        // Add products to inventory
        Product laptop = new Product("P001", "Gaming Laptop", 
                                   "High-performance gaming laptop", 1299.99, "Electronics", 10);
        Product mouse = new Product("P002", "Wireless Mouse", 
                                  "Ergonomic wireless mouse", 29.99, "Electronics", 50);
        Product keyboard = new Product("P003", "Mechanical Keyboard", 
                                     "RGB mechanical keyboard", 149.99, "Electronics", 25);
        Product book = new Product("P004", "Java Programming Book", 
                                 "Comprehensive Java guide", 49.99, "Books", 30);
        
        laptop.getTags().addAll(Arrays.asList("gaming", "laptop", "computer"));
        mouse.getTags().addAll(Arrays.asList("mouse", "wireless", "peripheral"));
        keyboard.getTags().addAll(Arrays.asList("keyboard", "mechanical", "rgb"));
        book.getTags().addAll(Arrays.asList("java", "programming", "education"));
        
        processor.addProduct(laptop);
        processor.addProduct(mouse);
        processor.addProduct(keyboard);
        processor.addProduct(book);
        
        // Customer shopping
        String customerId = "CUST001";
        
        // Add items to cart
        processor.addToCart(customerId, "P001", 1); // Laptop
        processor.addToCart(customerId, "P002", 2); // Mice
        processor.addToCart(customerId, "P003", 1); // Keyboard
        
        // Display cart
        ShoppingCart cart = processor.getCart(customerId);
        System.out.println("Shopping Cart:");
        cart.getItems().forEach((productId, item) -> {
            Product product = item.getProduct();
            System.out.printf("%s x%d - $%.2f each = $%.2f%n",
                product.getName(), item.getQuantity(), 
                product.getPrice(), product.getPrice() * item.getQuantity());
        });
        System.out.printf("Total: $%.2f%n", cart.calculateTotal());
        
        // Create order
        try {
            Order order = processor.createOrder(customerId, "123 Main St, City, State");
            System.out.println("\nOrder created: " + order.getOrderId());
            System.out.println("Order status: " + order.getStatus());
            System.out.printf("Order total: $%.2f%n", order.getTotalAmount());
            
            // Wait for order processing
            Thread.sleep(8000);
            
            System.out.println("Final order status: " + order.getStatus());
            
        } catch (InsufficientStockException e) {
            System.err.println("Order failed: " + e.getMessage());
        }
        
        // Search functionality
        System.out.println("\nSearch Results for 'gaming':");
        List<Product> searchResults = processor.searchProducts("gaming");
        searchResults.forEach(product -> 
            System.out.printf("%s - $%.2f (Stock: %d)%n", 
                product.getName(), product.getPrice(), product.getStockQuantity()));
        
        // Category browsing
        System.out.println("\nElectronics Category:");
        List<Product> electronics = processor.getProductsByCategory("Electronics");
        electronics.forEach(product -> 
            System.out.printf("%s - $%.2f%n", product.getName(), product.getPrice()));
        
        // Order statistics
        System.out.println("\nOrder Statistics:");
        Map<String, Long> stats = processor.getOrderStatistics();
        stats.forEach((status, count) -> 
            System.out.printf("%s: %d orders%n", status, count));
        
        processor.shutdown();
    }
}

Best Practices & Performance Optimization

Memory Management

Key Principles:
  • Use appropriate collection types
  • Implement proper equals() and hashCode()
  • Close resources with try-with-resources
  • Avoid memory leaks with listeners

// Efficient resource management
public class DataProcessor implements AutoCloseable {
    private final List<String> data;
    private final ExecutorService executor;
    
    public DataProcessor() {
        // Use ArrayList for indexed access
        this.data = new ArrayList<>();
        this.executor = Executors.newFixedThreadPool(4);
    }
    
    public void processLargeDataset(Path filePath) throws IOException {
        // Use try-with-resources for automatic cleanup
        try (BufferedReader reader = Files.newBufferedReader(filePath);
             Stream<String> lines = reader.lines()) {
            
            // Process in parallel for better performance
            List<CompletableFuture<String>> futures = lines
                .filter(line -> !line.trim().isEmpty())
                .map(line -> CompletableFuture.supplyAsync(() -> 
                    processLine(line), executor))
                .collect(Collectors.toList());
            
            // Collect results
            for (CompletableFuture<String> future : futures) {
                try {
                    data.add(future.get());
                } catch (InterruptedException | ExecutionException e) {
                    // Handle errors appropriately
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("Processing failed", e);
                }
            }
        }
    }
    
    private String processLine(String line) {
        // Simulate processing
        return line.toUpperCase().trim();
    }
    
    @Override
    public void close() {
        executor.shutdown();
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}
                        

Error Handling Strategies

Exception Handling Patterns:
  • Use specific exception types
  • Fail fast with validation
  • Log errors appropriately
  • Provide meaningful error messages

// Comprehensive error handling
public class UserService {
    private static final Logger logger = 
        LoggerFactory.getLogger(UserService.class);
    
    public User createUser(String email, String name, int age) 
            throws ValidationException, UserCreationException {
        
        // Input validation with specific exceptions
        validateUserInput(email, name, age);
        
        try {
            // Check if user already exists
            if (userExists(email)) {
                throw new UserCreationException(
                    "User with email " + email + " already exists");
            }
            
            User user = new User(email, name, age);
            saveUser(user);
            
            logger.info("Successfully created user: {}", email);
            return user;
            
        } catch (DatabaseException e) {
            logger.error("Database error while creating user: {}", email, e);
            throw new UserCreationException(
                "Failed to create user due to database error", e);
        } catch (Exception e) {
            logger.error("Unexpected error while creating user: {}", email, e);
            throw new UserCreationException(
                "An unexpected error occurred", e);
        }
    }
    
    private void validateUserInput(String email, String name, int age) 
            throws ValidationException {
        
        List<String> errors = new ArrayList<>();
        
        if (email == null || !isValidEmail(email)) {
            errors.add("Invalid email format");
        }
        
        if (name == null || name.trim().isEmpty()) {
            errors.add("Name cannot be empty");
        }
        
        if (age < 0 || age > 150) {
            errors.add("Age must be between 0 and 150");
        }
        
        if (!errors.isEmpty()) {
            throw new ValidationException(
                "Validation failed: " + String.join(", ", errors));
        }
    }
    
    // Retry mechanism for transient failures
    public <T> T executeWithRetry(Supplier<T> operation, int maxRetries) 
            throws Exception {
        
        Exception lastException = null;
        
        for (int attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                return operation.get();
            } catch (TransientException e) {
                lastException = e;
                logger.warn("Attempt {} failed, retrying... Error: {}", 
                          attempt, e.getMessage());
                
                if (attempt < maxRetries) {
                    try {
                        Thread.sleep(1000 * attempt); // Exponential backoff
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException("Interrupted during retry", ie);
                    }
                }
            }
        }
        
        throw new RuntimeException(
            "Operation failed after " + maxRetries + " attempts", lastException);
    }
}
                        

Unit Testing Examples

JUnit Test Examples


// StudentTest.java
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;

class StudentTest {
    private Student student;
    private Course javaCourse;
    private Course mathCourse;
    
    @BeforeEach
    void setUp() {
        student = new Student("S001", "John Doe", "john@email.com");
        javaCourse = new Course("CS101", "Java Programming", 3, "Dr. Smith", 30);
        mathCourse = new Course("MATH201", "Calculus", 4, "Dr. Johnson", 25);
    }
    
    @Test
    @DisplayName("Should enroll student in course successfully")
    void testEnrollInCourse() {
        student.enrollInCourse(javaCourse);
        
        assertTrue(student.getCourses().contains(javaCourse));
        assertTrue(javaCourse.getEnrolledStudents().contains(student));
    }
    
    @Test
    @DisplayName("Should prevent duplicate enrollment")
    void testPreventDuplicateEnrollment() {
        student.enrollInCourse(javaCourse);
        student.enrollInCourse(javaCourse); // Attempt duplicate
        
        assertEquals(1, student.getCourses().size());
        assertEquals(1, javaCourse.getEnrolledStudents().size());
    }
    
    @Test
    @DisplayName("Should calculate GPA correctly")
    void testGPACalculation() {
        student.addGrade("CS101", new Grade(3.7, 3)); // A = 3.7 * 3 = 11.1
        student.addGrade("MATH201", new Grade(3.0, 4)); // B+ = 3.0 * 4 = 12.0
        
        // Total points: 23.1, Total credits: 7
        // Expected GPA: 23.1 / 7 = 3.3
        assertEquals(3.3, student.calculateGPA(), 0.01);
    }
    
    @Test
    @DisplayName("Should return 0 GPA when no grades")
    void testZeroGPAWithNoGrades() {
        assertEquals(0.0, student.calculateGPA());
    }
    
    @Test
    @DisplayName("Should handle null course enrollment")
    void testNullCourseEnrollment() {
        assertThrows(NullPointerException.class, () -> {
            student.enrollInCourse(null);
        });
    }
}
                        

Bank Account Tests


// BankAccountTest.java
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;

class BankAccountTest {
    private SavingsAccount savingsAccount;
    private CheckingAccount checkingAccount;
    
    @BeforeEach
    void setUp() {
        savingsAccount = new SavingsAccount(
            "SAV001", "Alice Smith", 1000.0, 0.02);
        checkingAccount = new CheckingAccount(
            "CHK001", "Bob Johnson", 500.0, 200.0);
    }
    
    @Test
    @DisplayName("Should deposit money successfully")
    void testSuccessfulDeposit() {
        assertTrue(savingsAccount.deposit(500.0));
        assertEquals(1500.0, savingsAccount.getBalance(), 0.01);
    }
    
    @Test
    @DisplayName("Should reject negative deposit")
    void testNegativeDeposit() {
        assertThrows(IllegalArgumentException.class, () -> {
            savingsAccount.deposit(-100.0);
        });
    }
    
    @Test
    @DisplayName("Should withdraw within balance")
    void testValidWithdrawal() {
        assertTrue(savingsAccount.withdraw(300.0));
        assertEquals(700.0, savingsAccount.getBalance(), 0.01);
    }
    
    @Test
    @DisplayName("Should reject withdrawal exceeding balance for savings")
    void testExcessiveWithdrawalSavings() {
        assertFalse(savingsAccount.withdraw(1500.0));
        assertEquals(1000.0, savingsAccount.getBalance(), 0.01);
    }
    
    @Test
    @DisplayName("Should allow overdraft for checking account")
    void testOverdraftChecking() {
        assertTrue(checkingAccount.withdraw(600.0)); // $500 + $200 overdraft = $700 available
        assertEquals(-100.0, checkingAccount.getBalance(), 0.01);
    }
    
    @Test
    @DisplayName("Should track transaction history")
    void testTransactionHistory() {
        savingsAccount.deposit(200.0);
        savingsAccount.withdraw(150.0);
        
        List<Transaction> history = savingsAccount.getTransactionHistory();
        assertEquals(2, history.size());
        
        Transaction lastTransaction = history.get(history.size() - 1);
        assertEquals(TransactionType.WITHDRAWAL, lastTransaction.getType());
        assertEquals(150.0, lastTransaction.getAmount(), 0.01);
    }
    
    @ParameterizedTest
    @ValueSource(doubles = {0.0, -50.0, -1.0})
    @DisplayName("Should reject invalid withdrawal amounts")
    void testInvalidWithdrawalAmounts(double amount) {
        assertThrows(IllegalArgumentException.class, () -> {
            savingsAccount.withdraw(amount);
        });
    }
    
    @Test
    @DisplayName("Should apply monthly interest correctly")
    void testMonthlyInterest() {
        savingsAccount.applyMonthlyInterest();
        
        // Expected: 1000 + (1000 * 0.02 / 12) = 1000 + 1.67 = 1001.67
        assertEquals(1001.67, savingsAccount.getBalance(), 0.01);
    }
}
                        

Summary & Key Takeaways

Programming Concepts Applied

  • Object-Oriented Design: Inheritance, polymorphism, encapsulation
  • Collections Framework: Lists, Maps, Sets, Queues
  • Exception Handling: Custom exceptions, try-with-resources
  • Multithreading: ExecutorService, synchronization, CompletableFuture
  • File I/O: Serialization, NIO, resource management
  • Stream API: Filtering, mapping, collecting
  • Generics: Type safety, wildcards
  • Interfaces: Default methods, functional interfaces

Development Best Practices

  • SOLID Principles: Single responsibility, dependency injection
  • Design Patterns: Observer, Factory, Strategy
  • Error Handling: Fail-fast validation, meaningful exceptions
  • Performance: Efficient algorithms, proper synchronization
  • Testing: Unit tests, parameterized tests, mocking
  • Code Quality: Clean code, documentation, logging
  • Concurrency: Thread safety, deadlock prevention
  • Resource Management: AutoCloseable, proper cleanup

Real-World Application Architecture

These examples demonstrate how to build scalable, maintainable Java applications by:

  • Separating concerns with proper layering (data, business logic, presentation)
  • Using appropriate data structures for different use cases
  • Implementing robust error handling and logging
  • Applying concurrent programming for performance
  • Writing comprehensive tests for reliability
  • Following Java best practices and conventions

Java Programming Mastery

Complete Course Summary

Course Completion Checklist

  • ✅ Java Fundamentals & Syntax
  • ✅ Object-Oriented Programming
  • ✅ Exception Handling & File I/O
  • ✅ Collections Framework & Generics
  • ✅ Multithreading & Concurrency
  • ✅ Advanced Features & Best Practices
  • ✅ Real-World Application Development
  • ✅ Testing & Quality Assurance

Ready for Professional Java Development!

Continue learning: Spring Framework, Microservices, and Advanced Patterns