You are here
Home > java > Core Java >

Java 21 Coding Example- Hospital Management System

Java 21 Coding Example- Hospital Management SystemThis article presents an implementation of a Hospital Management System using Java 21. If we say using Java 21, it means we are free to use all the final features that are available till Java 21. It doesn’t matter whether a particular feature belongs to Java 8 or Java 21. The used feature should be available till Java 21.

Our focus would be on some progressive features such as sealed classes, records, pattern matching in switch, immutable collections, and formatted string output. Along the way, weโ€™ll also explore how these features simplify code design, improve safety, and enhance readability. The primary target of this article is to practice the most important & latest features of Java in a real world use case.

This article explores the implementation of a maintainable Hospital Management System (HMS) as a Java 21 Coding Example that will demonstrate various attributes such as patient registration, appointment scheduling, health record management, pharmacy inventory, billing, and reporting.

What will you learn from this Article?

By the end of this implementation, you should not only gain insights into how Java 21 can be applied in a real-world domain like hospital management application but also understand how modern Java features contribute to cleaner, safer, and more maintainable code. This should be enlightening article for readers, especially Java developers looking to explore Java 21 features in a real-world use case and make the concept crystal clear.

Problem Statement

Implement a Hospital Management System (HMS) that includes Patient Management, Appointment Scheduling, Electronic Health Records (EHR), Staff Management, Billing & Payments, Pharmacy & Inventory, Reporting etc. demonstrating modern Java 21 features such as sealed classes/interfaces, records, pattern matching in switch, immutable collections, formatted string output, Lambda Expression/Method References etc.

Java 21 Implementation

import java.util.List;

//===== Sealed Interfaces for Core Services =====

sealed interface Service permits Appointment, Billing, Report, EHR, Inventory {}
sealed interface User permits Patient, Staff {}

//===== User Types =====

record Patient(String id, String name, int age, String ailment) implements User {}
record Staff(String id, String name, String role) implements User {}

//===== Service Types =====

record Appointment(String patientId, String doctorName, String date) implements Service {}
record Billing(String patientId, double amount, String status) implements Service {}
record Report(String patientId, String details) implements Service {}

//===== New Feature: Electronic Health Records (EHR) =====

record EHR(String patientId, List<String> medicalHistory, List<String> prescriptions) implements Service {}

//===== New Feature: Pharmacy Inventory =====

record Inventory(String itemName, int quantity, String category) implements Service {}

public class HospitalManagementSystem {

     public static void main(String[] args) {
          
         // Sample Users
         List<User> users = List.of(
                 new Patient("P001", "Albert", 30, "Fever"),
                 new Patient("P002", "Mary", 45, "Fracture"),
                 new Staff("S001", "Dr. Smith", "Physician"),
                 new Staff("S002", "Nina", "Nurse")
         );

         // Sample Services Including EHR and Inventory
         List<Service> services = List.of(
                 new Appointment("P001", "Dr. Smith", "2025-04-08"),
                 new Billing("P002", 900.0, "Pending"),
                 new Report("P002", "Healing as expected"),
                 new EHR("P001", List.of("Diabetes", "Allergy to penicillin"), List.of("Paracetamol", "Vitamin D")),
                 new Inventory("Paracetamol", 150, "Medicine"),
                 new Inventory("Syringe", 300, "Equipment")
         );

         // Display Users
         System.out.println("=== User Info ===");
         users.forEach(HospitalManagementSystemV2::processUser);

         // Display Services
         System.out.println("\n=== Service Info ===");
         services.forEach(HospitalManagementSystemV2::processService);
    }    

    // ===== Pattern Matching Switch for Users =====
    static void processUser(User user) {
        switch (user) {
            case Patient p -> System.out.println(String.format(
                    "Patient[ID: %s, Name: %s, Age: %d, Ailment: %s]",
                    p.id(), p.name(), p.age(), p.ailment()));
            case Staff s -> System.out.println(String.format(
                    "Staff[ID: %s, Name: %s, Role: %s]",
                    s.id(), s.name(), s.role()));
        }
    }

    // ===== Pattern Matching Switch for All Services =====
    static void processService(Service service) {
        switch (service) {
            case Appointment a -> System.out.println(String.format(  
                     "Appointment[Patient ID: %s, Doctor: %s, Date: %s]",
                     a.patientId(), a.doctorName(), a.date()));
            case Billing b -> System.out.println(String.format(
                     "Billing[Patient ID: %s, Amount: $%.2f, Status: %s]",
                     b.patientId(), b.amount(), b.status()));
            case Report r -> System.out.println(String.format(
                     "Report[Patient ID: %s, Details: %s]",
                     r.patientId(), r.details()));
            case EHR ehr -> {
                     String history = String.join(", ", ehr.medicalHistory());
                     String prescriptions = String.join(", ", ehr.prescriptions());
                     System.out.println(String.format(
                     "EHR[Patient ID: %s, History: [%s], Prescriptions: [%s]]",
                     ehr.patientId(), history, prescriptions));
            }
            case Inventory inv -> System.out.println(String.format(
                     "Inventory[Item: %s, Quantity: %d, Category: %s]",
                     inv.itemName(), inv.quantity(), inv.category()));
         }
     }
}

Output:

=== User Info ===
Patient[ID: P001, Name: Albert, Age: 30, Ailment: Fever]
Patient[ID: P002, Name: Mary, Age: 45, Ailment: Fracture]
Staff[ID: S001, Name: Dr. Smith, Role: Physician]
Staff[ID: S002, Name: Nina, Role: Nurse]
=== Service Info ===
Appointment[Patient ID: P001, Doctor: Dr. Smith, Date: 2025-04-08]
Billing[Patient ID: P002, Amount: $900.00, Status: Pending]
Report[Patient ID: P002, Details: Healing as expected]
EHR[Patient ID: P001, History: [Diabetes, Allergy to penicillin], Prescriptions: [Paracetamol, Vitamin D]]
Inventory[Item: Paracetamol, Quantity: 150, Category: Medicine]
Inventory[Item: Syringe, Quantity: 300, Category: Equipment]

Explanation of Key Java 21 Features Used

Feature Applied To Benefit
sealed interface Service permits … Restricts which service types can implement the interface Ensures compile-time safety and exhaustive handling
record EHR(…) and record Inventory(…) Represents immutable value types Auto-generates constructor, getters, toString(), etc.
switch (service) with pattern matching Avoids verbose instanceof + cast Cleaner and safer type branching
List.of(…) Used for medical history, prescriptions, inventory list Immutable and safer by design
String.format(…) Used for all formatted output Replaces clumsy string concatenation

Billing & Payments System Implementation in Java 21

This module demonstrate how to implement complex billing logic using Java 21.

Problem Statement

Calculate the billing amount for patient services (consultation, lab tests, medicines), apply insurance (if applicable), and process payments.

Business Rules:

  • Every patient visit may include:

    • Consultation: โ‚น500

    • Lab Tests: โ‚น1000

    • Medications: variable, from inventory

  • Insurance Plans:

    • None: No discount

    • Basic: 20% discount

    • Premium: 40% discount

  • Final bill = (Consultation + Lab + Medication) – Insurance discount

Solution

import java.util.List;
import java.util.Map;

sealed interface Insurance permits NoneInsurance, BasicInsurance, PremiumInsurance {}
record NoneInsurance() implements Insurance {}
record BasicInsurance() implements Insurance {}
record PremiumInsurance() implements Insurance {}

record BillingDetails(
    boolean consultation,
    boolean labTest,
    List<String> medications,
    Insurance insurance
) {}

public class BillingModule {
    private static final Map<String, Double> medicationCosts = Map.of(
        "Paracetamol", 50.0,
        "Antibiotic", 150.0,
        "Vitamin D", 100.0
    );

    public static void main(String[] args) {
        BillingDetails bill = new BillingDetails(
            true, true,
            List.of("Paracetamol", "Vitamin D"),
            new PremiumInsurance()
       );
       double total = calculateBill(bill);
       System.out.println(String.format("Final Billing Amount: $%.2f", total));
    }

    public static double calculateBill(BillingDetails details) {
        double total = 0;
        if (details.consultation()) total += 500;
        if (details.labTest()) total += 1000;
          
        for (String med : details.medications()) {
           total += medicationCosts.getOrDefault(med, 0.0);
        }

        double discount = switch (details.insurance()) {
            case BasicInsurance b -> 0.20;   
            case PremiumInsurance p -> 0.40;
            case NoneInsurance n -> 0.0;
        };

        return total * (1 - discount);
    }
}

Output

Final Billing Amount: $990.00

Reporting & Analytics Moduleย Implementation as a Java 21 Coding Example

Problem Statement

Classify and summarize hospital usage statistics using Java 21 & features like records and switch-case pattern matching. Follow the below business rules.

Business Rules:

  • Categorize data by:

    • Visits per department

    • Revenue generated per module

    • Top prescribed medications

  • Should support different types of reports via diverse reporting models.

Solutionย 

import java.util.List;
import java.util.Map;

sealed interface Report permits RevenueReport, VisitReport, MedicationReport {}
record RevenueReport(Map<String, Double> revenueByModule) implements Report {}
record VisitReport(Map<String, Integer> visitsByDept) implements Report {}
record MedicationReport(Map<String, Integer> medsPrescribed) implements Report {}

public class ReportModule {
     public static void main(String[] args) {
         List<Report> reports = List.of(
             new RevenueReport(Map.of("Billing", 100000.0, "Pharmacy", 50000.0)),
             new VisitReport(Map.of("Cardiology", 50, "Pediatrics", 75)),
             new MedicationReport(Map.of("Paracetamol", 120, "Antibiotic", 85))
         );

         for (Report report : reports) {
             printReport(report);
         } 
     }

     static void printReport(Report report) {
         switch (report) {
             case RevenueReport r -> r.revenueByModule()
                       .forEach((k, v) -> System.out.printf("%s Revenue: โ‚น%.2f%n", k, v));
             case VisitReport v -> v.visitsByDept()
                       .forEach((k, val) -> System.out.printf("Visits in %s: %d%n", k, val));
             case MedicationReport m -> m.medsPrescribed()
                       .forEach((med, count) -> System.out.printf("%s prescribed: %d times%n", med, count));
         }
     }
}

Output

Pharmacy Revenue: โ‚น50000.00
Billing Revenue: โ‚น100000.00
Visits in Pediatrics: 75
Visits in Cardiology: 50
Antibiotic prescribed: 85 times
Paracetamol prescribed: 120 times

Electronic Health Records (EHR) Module Implementation as a Java 21 Coding Example

Problem Statement

Implement ETH (Electronic Health Records) using Java 21 features. Follow the below business rules.

Business Rules:

  • Each patient has a list of medical records.

  • A medical record includes diagnosis, treatment, attending doctor, and record date.

  • EHR can be queried by patient or doctor.

  • A sealed interface differentiates record types: DiagnosisRecord, SurgeryRecord, MedicationRecord.

Solutionย 

import java.time.LocalDate;
import java.util.*;

sealed interface MedicalRecord permits DiagnosisRecord, SurgeryRecord, MedicationRecord {}
record DiagnosisRecord(String diagnosis, String doctor, LocalDate date) implements MedicalRecord {}
record SurgeryRecord(String surgeryType, String surgeon, LocalDate date) implements MedicalRecord {}
record MedicationRecord(String medication, String prescribedBy, int dosageMg, LocalDate date) implements MedicalRecord {}
record PatientEHR(String patientId, List<MedicalRecord> records) {}

public class EHRModule {

    private static final Map<String, PatientEHR> ehrDatabase = new HashMap<>();

    public static void main(String[] args) {
         MedicalRecord r1 = new DiagnosisRecord("Flu", "Dr. Singh", LocalDate.now().minusDays(5));
         MedicalRecord r2 = new MedicationRecord("Paracetamol", "Dr. Singh", 500, LocalDate.now().minusDays(4));
         MedicalRecord r3 = new SurgeryRecord("Appendectomy", "Dr. Mehta", LocalDate.now().minusYears(1));
         
         ehrDatabase.put("P001", new PatientEHR("P001", List.of(r1, r2, r3)));
         
         printEHR("P001");
    }

    static void printEHR(String patientId) {
         PatientEHR ehr = ehrDatabase.get(patientId);
         if (ehr == null) {
            System.out.println("No records found.");
         return;
         }
         System.out.println("EHR for patient: " + patientId);

         for (MedicalRecord record : ehr.records()) {
            switch (record) {
                case DiagnosisRecord d -> System.out.printf("Diagnosis: %s by %s on %s%n", d.diagnosis(), d.doctor(), d.date());
                case MedicationRecord m -> System.out.printf("Medication: %s (%dmg) prescribed by %s on %s%n", m.medication(), m.dosageMg(), m.prescribedBy(), m.date());
                case SurgeryRecord s -> System.out.printf("Surgery: %s by %s on %s%n", s.surgeryType(), s.surgeon(), s.date());
            }
        }
    }
}

Output

EHR for patient: P001
Diagnosis: Flu by Dr. Singh on 2025-04-07
Medication: Paracetamol (500mg) prescribed by Dr. Singh on 2025-04-08
Surgery: Appendectomy by Dr. Mehta on 2024-04-12

Pharmacy & Inventory Module Implementation as a Java 21 Coding Example

Problem Statement

Implement Pharmacy & Inventory Module using Java 21 features. Follow the below business rules.

Business Rules:

  • Each medicine has name, quantity, and expiry date.

  • Inventory supports:

    • Adding stock

    • Dispensing medication

    • Checking expired medications

Solutionย 

import java.time.LocalDate;
import java.util.*;

record Medicine(String name, int quantity, LocalDate expiryDate) {}

public class InventoryModule {
     private static final Map<String, Medicine> inventory = new HashMap<>();
     public static void main(String[] args) {
          addMedicine(new Medicine("Paracetamol", 100, LocalDate.of(2025, 12, 31)));
          addMedicine(new Medicine("Amoxicillin", 50, LocalDate.of(2023, 12, 31))); // Expired
          dispense("Paracetamol", 10);
          dispense("Amoxicillin", 5); // Should warn
          showInventory();
     }

     static void addMedicine(Medicine medicine) {
          inventory.merge(medicine.name(), medicine, (oldMed, newMed) -> 
               new Medicine(oldMed.name(), oldMed.quantity() + newMed.quantity(), newMed.expiryDate())
          );
     }

     static void dispense(String name, int qty) {
          Medicine med = inventory.get(name);
          if (med == null) {
              System.out.println("Medicine not available.");
              return;
          }
          if (med.expiryDate().isBefore(LocalDate.now())) {
              System.out.println("Medicine expired: " + name);
              return;
          }
          if (med.quantity() < qty) {
              System.out.println("Insufficient stock.");
              return;
          }
          inventory.put(name, new Medicine(name, med.quantity() - qty, med.expiryDate()));
          System.out.printf("Dispensed %d units of %s%n", qty, name);
     }

     static void showInventory() {
          System.out.println("\nCurrent Inventory:");
          for (Medicine med : inventory.values()) {  
              System.out.printf("%s - Qty: %d, Expiry: %s%n", med.name(), med.quantity(), med.expiryDate());
          }
     }
}

Output

Dispensed 10 units of Paracetamol
Medicine expired: Amoxicillin

Current Inventory:
Paracetamol - Qty: 90, Expiry: 2025-12-31
Amoxicillin - Qty: 50, Expiry: 2023-12-31

Modular Approach Implementation Using Java 21

Problem Statement

Implement a modular and maintainable Hospital Management System (HMS) using modern Java 21 features, demonstrating Patient Management, Appointment Scheduling, Electronic Health Records (EHR), Staff Management, Billing & Payments, Pharmacy & Inventory, Reporting & Analytics. Below is the functional scope of the implementation:

Functional Scope

Your task is to design and implement a simplified but extensible Hospital Management System that includes the following core modules:

Patient Management: Register and track patients’ basic demographics and ailments.

Appointment Scheduling: Assign appointments between patients and doctors on specified dates. Prevent overlapping appointments for the same doctor.

Electronic Health Records (EHR): Store and retrieve medical history and prescription data per patient. Support multiple entries per patient, sorted chronologically.

Staff Management: Maintain a list of staff members, including their roles (doctor, nurse, admin).

Billing and Payments: Generate bills based on patient treatments. Track payment status (e.g., Pending, Paid).

Pharmacy & Inventory Management: Keep a record of medical supplies and medicines with their quantities. Alert when stock levels fall below a specified threshold.

Reporting & Analytics: Generate summary reports on appointments, billing, EHR access, and inventory status.

Technical Objectives

Implement this system using Java 21 features that promote modern, readable, and safe code practices. Your implementation should showcase the following capabilities:

  • Sealed Interfaces and Classes: Enforce strict type hierarchies for core models like Service and User.

  • Records: Use immutable data structures to represent entities such as patients, appointments, and health records.

  • Pattern Matching in switch: Replace traditional instanceof checks with cleaner, type-safe branching logic.

  • Immutable Collections using List.of(): Define fixed-size data collections, improving safety and thread-friendliness.

  • Formatted Output using String.format(): Ensure consistent and readable output for logs, reports, and user feedback.

  • Lambda Expression/Method References: Use these features whenver needed to accomplish functional programming.

Your code should be modular, easy to test, and capable of extension for future features such as role-based access control, user authentication, or integration with external APIs.

Java 21 Implementation & Features Explanation

//------------------------------

//1. PATIENT MANAGEMENT MODULE

//------------------------------

import java.util.List;

public record Patient(int id, String name, int age, String gender) {}

class PatientService {

    private final List<Patient> patients = List.of(
               new Patient(1, "Mary", 30, "Female"),
               new Patient(2, "Albert", 45, "Male"),
               new Patient(3, "John", 60, "Male")
    );

    public List<Patient> getAllPatients() {
       return patients;
    }
}

//------------------------------

//2. APPOINTMENT SCHEDULING

//------------------------------

sealed interface StaffRole permits Doctor, Nurse, Admin {}
record Doctor(String specialization) implements StaffRole {}
record Nurse() implements StaffRole {}
record Admin() implements StaffRole {}
record Staff(int id, String name, StaffRole role) {}
record Appointment(Patient patient, Staff doctor, String time) {}

class AppointmentService {

    public Appointment scheduleAppointment(Patient patient, Staff staff, String time) {
        return switch (staff.role()) {
             case Doctor d -> new Appointment(patient, staff, time);
             default -> throw new IllegalArgumentException("Only doctors can have appointments.");
       };
    }
}

//------------------------------

//3. ELECTRONIC HEALTH RECORDS (EHR)

//------------------------------

import java.time.LocalDate;

record EHR(Patient patient, LocalDate date, String diagnosis, List<String> prescriptions) {}

class EHRService {
    public void printEHR(EHR ehr) {
        System.out.println(String.format("\n--- EHR for %s ---\nDate: %s\nDiagnosis: %s\nPrescriptions: %s\n",
        ehr.patient().name(), ehr.date(), ehr.diagnosis(), ehr.prescriptions()));
    }
}

//------------------------------

//4. STAFF MANAGEMENT

//------------------------------

class StaffService {

    private final List<Staff> staffList = List.of(
         new Staff(101, "Dr. Jane", new Doctor("Cardiology")),
         new Staff(102, "Nurse Mike", new Nurse()),
         new Staff(103, "Admin Lisa", new Admin())
    );

    public void printStaffRoles() {
        for (Staff s : staffList) {
           String roleDescription = switch (s.role()) {
              case Doctor d -> "Doctor - " + d.specialization();
              case Nurse n -> "Nurse";
              case Admin a -> "Administrative Staff";
          };
          System.out.println(s.name() + ": " + roleDescription);
        }
    }
}

//------------------------------

//5. BILLING & PAYMENTS

//------------------------------

enum PaymentStatus { PENDING, PAID; }

record Billing(Appointment appointment, double amount, PaymentStatus status) {}

class BillingService {
    public Billing generateBill(Appointment appt) {
        double base = switch (((Doctor) appt.doctor().role()).specialization()) {
             case "Cardiology" -> 1500;
             case "Neurology" -> 2000;
             default -> 1000;
        };
        return new Billing(appt, base, PaymentStatus.PENDING);
    }
}

//------------------------------

//6. PHARMACY & INVENTORY

//------------------------------

sealed interface InventoryItem permits Medicine, Equipment, Consumable {}
record Medicine(String name, int quantity) implements InventoryItem {}
record Equipment(String name, int quantity) implements InventoryItem {}
record Consumable(String name, int quantity) implements InventoryItem {}

class InventoryService {
    private final List<InventoryItem> items = List.of(
         new Medicine("Paracetamol", 100),
         new Equipment("X-Ray Machine", 2),
         new Consumable("Syringes", 500)
    );

    public void checkInventory() {
       for (InventoryItem item : items) {
          String info = switch (item) {
            case Medicine m -> String.format("Medicine: %s, Qty: %d", m.name(), m.quantity());
            case Equipment e -> String.format("Equipment: %s, Qty: %d", e.name(), e.quantity());
            case Consumable c -> String.format("Consumable: %s, Qty: %d", c.name(), c.quantity());
          };
          System.out.println(info);
       }
   }
}

Explanation of Used Features & their Benefits

Features Used: sealed, record, List.of(), switch pattern matching, String.format()

  • Patients are represented using immutable records.

  • Sealed interface ensures only permitted types (like Patient) implement Person.
  • Doctors are part of a sealed hierarchy (sealed interface StaffRole permits Doctor, Nurse, Admin).

  • Appointments are scheduled only for doctors. Pattern-matching on Staff to filter only doctors.

  • Pattern matching in switch makes role validation cleaner.

  • A central list of patients is initialized with List.of(…).

  • EHR entries are modeled as records to ensure immutability.

  • String formatting provides consistent output.

Benefits:

  • Records provide a concise model and reduce boilerplate (getters, equals, hashCode, toString).

  • Sealed classes prevent unwanted implementations.

  • Pattern matching improves type safety and readability.

  • Immutable collections prevent accidental modification.

TODO: REST API endpoints using Spring Boot

Letโ€™s now further extend the examples & build REST API endpoints using Spring Boot for below two module of our Hospital Management System. These endpoints will expose RESTful APIs for operations like retrieving patient records, adding medicines, dispensing medication, etc. Below are the two modules:

  • Electronic Health Records (EHR)

  • Pharmacy & Inventory

Conclusion

If you’re working on modernizing legacy applications or designing new projects, adopting Java 21 can be a good choice for your implementation needs.ย In this comprehensive Hospital Management System, we explored how to modernize a typical enterprise-level Java application using the powerful features introduced till Java 21. By utilizing sealed interfaces, records, pattern matching in switch, and immutable collections, we were able to:

  • Build a more maintainable and concise codebase

  • Improve safety with restricted class hierarchies

  • Reduce boilerplate and enhance readability

  • Provide a foundation that is both clean and extensible for real-world healthcare applications

This implementation not only serves as a great learning resource for developers upgrading to Java 21, but also showcases how modern language features can simplify complex business logic in domain-driven designs. Whether youโ€™re building microservices, enterprise apps, or domain-driven designs like this HMS, these features make your codebase more robust and future-proof.


You may also go through: Java System Design- Hospital Management System

Additionally,ย  Java 21 Features with Examples.


References

https://www.oracle.com/java/technologies/javase/21-relnote-issues.html

Leave a Reply


Top