'자바 대출 이자 계산기 구현하기 (원금균등상환, 원리금 균등상환, 만기 일시상환)'
대출 시 이자 상환 방식에는 원금균등상환, 원리금 균등상환 그리고 만기 일시상환 세 가지가 있으며, 각 방식에 따라서 이자 금액에 차이가 있을 뿐만 아니라 재정 계획에 영향을 줄 수 있습니다. 아래에서는 각 방식에 대한 간단한 내용과 구현된 코드를 볼 수 있습니다.
'원금균등상환'
매월 동일한 원금과 남은 잔금에 상응하는 이자를 더한 금액을 매월 상환하는 방식입니다.
즉, 1천만 원을 3%의 이율로 12개월간 대출한 경우 매월 833,333원의 원금을 상환하며, 대출 잔금에 3% 이자율을 적용한 이자를 함께 상환합니다.
잔금이 매월 줄어들기 때문에 그에 따른 이자가 줄어들어 3가지 방식 중 총이자 금액이 가장 저렴하다는 장점이 있습니다.
    // 원금균등상환
    public static List<Loan> calculateLoanPayment1(Long loanAmount, int loanTerm, double interestRate) {
        Long loanBalance = loanAmount;                   // 남은 대출 원금
        Long monthlyPayment = loanAmount / loanTerm;     // 매달 상환해야하는 원금
        Long interestTotal = 0L;                         // 총 이자 합계
        double yearInterestRate = interestRate / 12 / 100;        // 대출 이자율 (연이자율 / 12)
        for (int i = 1; i <= loanTerm; i++) {
            Long monthlyInterest = Math.round(loanBalance * yearInterestRate);   // 월 납부 이자
            interestTotal = interestTotal + monthlyInterest;                     // 이자 합계 추가
            loanBalance = (loanBalance - monthlyPayment < 0) ? 0 : (loanBalance - monthlyPayment);      // 남은 대출 원금
            Loan repaymentItem = Loan.builder()
                    .count(i)
                    .monthlyPayment(monthlyPayment)
                    .monthlyInterest(monthlyInterest)
                    .monthlyPaymentTotal(monthlyPayment + monthlyInterest)
                    .loanBalance(0L)
                    .interestTotal(interestTotal)
                    .build();
            loanList.add(repaymentItem);
        }
        return (loanList.size() == 0) ? null : loanList;
    }
(loanAmount : 대출 금액, loanTerm : 대출 기간, interestRate : 이자율)
'원리금 균등상환'
매월 동일한 원금과 이자를 상환하는 방식입니다.
즉, 1천만 원을 3%의 이자율로 12개월간 대출 시 매월 846,936원의 일정한 금액으로 상환합니다.
시간이 지날수록 상환하는 금액에서 납입 원금 비율이 증가하고, 이자가 감소하는 개념이며 원금균등상환보다 총이자 금액이 높습니다.

    // 원리금균등상환
    public static List<Loan> calculateLoanPayment2(Long loanAmount, int loanTerm, double interestRate) {
        Long loanBalance = loanAmount;                   // 남은 대출 원금
        Long interestTotal = 0L;                         // 총 이자 합계
        double yearInterestRate = interestRate / 12 / 100;        // 대출 이자율 (연이자율 / 12)
        double denominator = Math.pow(yearInterestRate + 1, loanTerm) -1;                                   // 분모
        double molecule = loanAmount * yearInterestRate * ((Math.pow(yearInterestRate + 1, loanTerm)));     // 분자
        Long monthlyPaymentTotal = Math.round(molecule / denominator);    // 월 상환금
        for (int i = 1; i <= loanTerm; i++) {
            Long monthlyInterest = Math.round(loanBalance * yearInterestRate);   // 월 납부 이자
            interestTotal = interestTotal + monthlyInterest;                     // 이자 합계 추가
            Long monthlyPayment = monthlyPaymentTotal - monthlyInterest;         // 상환할 원금
            loanBalance = (loanBalance - monthlyPayment < 0) ? 0 : (loanBalance - monthlyPayment);      // 남은 대출 원금
            Loan repaymentItem = Loan.builder()
                    .count(i)
                    .monthlyPayment(monthlyPayment)
                    .monthlyInterest(monthlyInterest)
                    .monthlyPaymentTotal(monthlyPayment + monthlyInterest)
                    .loanBalance(loanBalance)
                    .interestTotal(interestTotal)
                    .build();
            loanList.add(repaymentItem);
        }
        return (loanList.size() == 0) ? null : loanList;
    }
(loanAmount : 대출 금액, loanTerm : 대출 기간, interestRate : 이자율)
'만기 일시상환'
대출기간 동안 매월 이자만 상환하는 방식입니다.
매월 상환금에 일정 수준의 원금을 포함하는 앞의 두 방법과는 다르게 대출 만기 시 원금을 일시에 상환하기 때문에 매월 원금이 줄어들지 않아 이자 금액이 높다는 단점이 있습니다.
마찬가지로 1천만 원을 3%의 이율로 12개월 동안 대출했을 때, 첫 달부터 마지막 전 달까지 25,000원을 납부하고 마지막 달에 원금인 1천만 원 + 25,000원을 납부하게 됩니다.
    // 만기일시상환
    public static List<Loan> calculateLoanPayment3(Long loanAmount, int loanTerm, double interestRate) {
        Long loanBalance = loanAmount;                   // 남은 대출 원금
        Long interestTotal = 0L;                         // 총 이자 합계
        double yearInterestRate = interestRate / 12 / 100;        // 대출 이자율 (연이자율 / 12)
        for (int i = 1; i <= loanTerm; i++) {
            // 마지막 납부 전까지는 이자만 납부
            if (i < loanTerm) {
                Long monthlyInterest = Math.round(loanBalance * yearInterestRate);   // 월 납부 이자
                interestTotal = interestTotal + monthlyInterest;                     // 이자 합계 추가
                Loan repaymentItem = Loan.builder()
                        .count(i)
                        .monthlyPayment(0L)
                        .monthlyInterest(monthlyInterest)
                        .monthlyPaymentTotal(monthlyInterest)
                        .loanBalance(loanBalance)
                        .interestTotal(interestTotal)
                        .build();
                loanList.add(repaymentItem);
            }
            // 마지막 납부 때 이자와 원금 납부
            else {
                Long monthlyInterest = Math.round(loanBalance * yearInterestRate);   // 월 납부 이자
                interestTotal = interestTotal + monthlyInterest;                     // 이자 합계 추가
                Loan repaymentItem = Loan.builder()
                        .count(i)
                        .monthlyPayment(loanBalance)
                        .monthlyInterest(monthlyInterest)
                        .monthlyPaymentTotal(loanBalance + monthlyInterest)
                        .loanBalance(loanBalance)
                        .interestTotal(interestTotal)
                        .build();
                loanList.add(repaymentItem);
            }
        }
        return (loanList.size() == 0) ? null : loanList;
    }
(loanAmount : 대출 금액, loanTerm : 대출 기간, interestRate : 이자율)
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@Setter
public class Loan {
    private int count;                  // 회차
    private Long monthlyPayment;        // 납입원금
    private Long monthlyInterest;       // 대출이자 
    private Long monthlyPaymentTotal;   // 월상환금
    private Long loanBalance;           // 대출잔금
    private Long interestTotal;         // 이자 합계
}
Loan class (lombok 사용)
'Programming > Java' 카테고리의 다른 글
| LocalDateTime toString() 메서드 사용 시 주의해야 할 점(00초 사라짐) (0) | 2022.01.20 | 
|---|---|
| 전문통신이란? Java 전문통신(Fixed Length Format) 문자열 길이 맞추는 메서드 (2) | 2022.01.19 | 
| Java 날짜와 문자열 LocalDateTime, String 변환하기 (0) | 2022.01.08 | 
| 자바 추상 클래스와 인터페이스의 차이점 이해하기 (2) | 2022.01.06 | 
| 메소드 오버로딩(Overloading)과 오버라이딩(Overriding)의 차이 이해하기 (0) | 2022.01.03 |