Created
June 10, 2026 07:55
-
-
Save stupidly-logical/c2e548daaa5ca5878db415cec5ad3a76 to your computer and use it in GitHub Desktop.
Using abstract class in Java to avoid duplicate code with clear separation of responsibility via utility classes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.*; | |
| import java.util.stream.IntStream; | |
| interface Bank { | |
| void assignLoans(int[] loans); | |
| void averageLoan(); | |
| void maxLoan(); | |
| void minLoan(); | |
| } | |
| final class LoanStats { | |
| private final double average; | |
| private final int max; | |
| private final int min; | |
| LoanStats(double average, int max, int min) { | |
| this.average = average; | |
| this.max = max; | |
| this.min = min; | |
| } | |
| double getAverage() { | |
| return average; | |
| } | |
| int getMax() { | |
| return max; | |
| } | |
| int getMin() { | |
| return min; | |
| } | |
| } | |
| final class LoanStatsCalculator { | |
| private LoanStatsCalculator() { | |
| // Utility class: prevent object creation | |
| } | |
| static LoanStats calculate(int[] loans) { | |
| if (loans == null || loans.length == 0) { | |
| return new LoanStats(0.0, 0, 0); | |
| } | |
| IntSummaryStatistics stats = Arrays.stream(loans).summaryStatistics(); | |
| return new LoanStats( | |
| stats.getAverage(), | |
| stats.getMax(), | |
| stats.getMin() | |
| ); | |
| } | |
| } | |
| final class ReportPrinter { | |
| private ReportPrinter() { | |
| // Utility class: prevent object creation | |
| } | |
| static void printDecimal(String prefix, String customerType, double value) { | |
| System.out.printf("%s %s is %.2f%n", prefix, customerType, value); | |
| } | |
| static void printInteger(String prefix, String customerType, int value) { | |
| System.out.printf("%s %s is %d%n", prefix, customerType, value); | |
| } | |
| static void printProcessed(String customerType) { | |
| System.out.printf("Loans for %s processed%n", customerType); | |
| } | |
| } | |
| abstract class AbstractLoanDepartment implements Bank { | |
| private final String customerType; | |
| private final String averagePrefix; | |
| private final String maxPrefix; | |
| private final String minPrefix; | |
| private final int[] loanAmounts; | |
| protected AbstractLoanDepartment( | |
| int customerCount, | |
| String customerType, | |
| String averagePrefix, | |
| String maxPrefix, | |
| String minPrefix | |
| ) { | |
| if (customerCount < 0) { | |
| throw new IllegalArgumentException("Customer count cannot be negative"); | |
| } | |
| this.customerType = customerType; | |
| this.averagePrefix = averagePrefix; | |
| this.maxPrefix = maxPrefix; | |
| this.minPrefix = minPrefix; | |
| this.loanAmounts = new int[customerCount]; | |
| ReportPrinter.printProcessed(customerType); | |
| } | |
| @Override | |
| public void assignLoans(int[] loans) { | |
| if (loans == null) { | |
| throw new IllegalArgumentException("Loans cannot be null"); | |
| } | |
| if (loans.length != loanAmounts.length) { | |
| throw new IllegalArgumentException("Loan count must match customer count"); | |
| } | |
| System.arraycopy(loans, 0, loanAmounts, 0, loans.length); | |
| } | |
| @Override | |
| public void averageLoan() { | |
| LoanStats stats = LoanStatsCalculator.calculate(loanAmounts); | |
| ReportPrinter.printDecimal(averagePrefix, customerType, stats.getAverage()); | |
| } | |
| @Override | |
| public void maxLoan() { | |
| LoanStats stats = LoanStatsCalculator.calculate(loanAmounts); | |
| ReportPrinter.printInteger(maxPrefix, customerType, stats.getMax()); | |
| } | |
| @Override | |
| public void minLoan() { | |
| LoanStats stats = LoanStatsCalculator.calculate(loanAmounts); | |
| ReportPrinter.printInteger(minPrefix, customerType, stats.getMin()); | |
| } | |
| } | |
| class PersonalLoanDept extends AbstractLoanDepartment { | |
| public PersonalLoanDept(int clients) { | |
| super( | |
| clients, | |
| "clients", | |
| "Average loan amount for", | |
| "Maximum loan amount amongst", | |
| "Minimum loan amount amongst" | |
| ); | |
| } | |
| } | |
| class BusinessLoanDept extends AbstractLoanDepartment { | |
| public BusinessLoanDept(int businesses) { | |
| super( | |
| businesses, | |
| "businesses", | |
| "Average loan amount for", | |
| "Maximum loan amongst", | |
| "Minimum loan amongst" | |
| ); | |
| } | |
| } | |
| public class Solution { | |
| public static void main(String[] args) { | |
| Scanner scanner = new Scanner(System.in); | |
| String[] counts = scanner.nextLine().trim().split("\\s+"); | |
| int clientCount = Integer.parseInt(counts[0]); | |
| int businessCount = Integer.parseInt(counts[1]); | |
| Bank personalLoanDept = new PersonalLoanDept(clientCount); | |
| Bank businessLoanDept = new BusinessLoanDept(businessCount); | |
| int[] clientLoans = parseLoans(scanner.nextLine()); | |
| int[] businessLoans = parseLoans(scanner.nextLine()); | |
| personalLoanDept.assignLoans(clientLoans); | |
| businessLoanDept.assignLoans(businessLoans); | |
| personalLoanDept.averageLoan(); | |
| personalLoanDept.maxLoan(); | |
| personalLoanDept.minLoan(); | |
| businessLoanDept.averageLoan(); | |
| businessLoanDept.maxLoan(); | |
| businessLoanDept.minLoan(); | |
| scanner.close(); | |
| } | |
| private static int[] parseLoans(String line) { | |
| if (line == null || line.trim().isEmpty()) { | |
| return new int[0]; | |
| } | |
| return Arrays.stream(line.trim().split("\\s+")) | |
| .mapToInt(Integer::parseInt) | |
| .toArray(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment