java版 银行还款计算

原型图是这样的(下图),要求算出每个月不同的还款方式的明细

废话不多说,代码

package org.com.rsmall.wx.vo;

import org.com.rsmall.db.vo.RepaymentDetailVo;

import java.math.BigDecimal;
import java.util.List;

/**
 * 银行还款计算
 */
public class BankRefund {

    /**
     * 先息后本
     * @param money  贷款总额
     * @param yearRate   贷款商业利率
     * @param months 贷款月数
     */
    public  static void foreInterest(Double money, Double yearRate, Integer months,List<RepaymentDetailVo> repaymentDetails){
        BigDecimal amount = new BigDecimal(money.toString());

        BigDecimal monthRate=resBigDecimalMonthRate(yearRate);
        BigDecimal interest = monthRate.multiply(amount).setScale(6,BigDecimal.ROUND_HALF_UP);

        BigDecimal totalMonthly=new BigDecimal("0");
        BigDecimal totalMonthlyCapital=new BigDecimal("0");
        BigDecimal totalMonthlyInterest=new BigDecimal("0");
        for (int i = 1; i <= months; i++) {
            RepaymentDetailVo repaymentDetailVo = new RepaymentDetailVo();
            repaymentDetailVo.setPeriods(i+"");
            if(months==i){
                repaymentDetailVo.setMonthlyCapital(amount.toString());
                repaymentDetailVo.setCapitalBalance("0.0000");
                repaymentDetailVo.setMonthly(amount.add(interest).toString());
            }else {
                repaymentDetailVo.setMonthlyCapital("0.0000");
                repaymentDetailVo.setCapitalBalance(amount.toString());
                repaymentDetailVo.setMonthly(interest.toString());
            }
            repaymentDetailVo.setMonthlyInterest(interest.toString());
            repaymentDetails.add(repaymentDetailVo);
            totalMonthly=totalMonthly.add(new BigDecimal(repaymentDetailVo.getMonthly()));
            totalMonthlyCapital=totalMonthlyCapital.add(new BigDecimal(repaymentDetailVo.getMonthlyCapital()));
            totalMonthlyInterest=totalMonthlyInterest.add(new BigDecimal(repaymentDetailVo.getMonthlyInterest()));
        }
        RepaymentDetailVo totalRepayment = new RepaymentDetailVo();
        totalRepayment.setPeriods("总计");
        totalRepayment.setCapitalBalance("---");
        totalRepayment.setMonthly(totalMonthly.toString());
        totalRepayment.setMonthlyInterest(totalMonthlyInterest.toString());
        totalRepayment.setMonthlyCapital(totalMonthlyCapital.toString());
        repaymentDetails.add(totalRepayment);
    }

    /**
     * 等额本金还款法【利息少,但前期还的多】
     * @param money  贷款总额
     * @param yearRate   贷款商业利率
     * @param months 贷款月数
     */
    public static void principal(Double money, Double yearRate, Integer months,List<RepaymentDetailVo> repaymentDetailVos) {
        //月利率
        Double monthRate = resDoubleMonthRate(yearRate);
        //每月还款本金
        Double monthPri = money / months;
        //还款总利息
        Double totalInterest = (months + 1) * money * monthRate / 2;
        //还款总额
        Double totalMoney = money + totalInterest;
        //第一个月还款金额
        Double firstMonth = monthPri + money * monthRate;
        //每月利息递减
        Double decreaseMonth = monthPri * monthRate;
        //总计已还款本金
        Double totalCapital=0.00;
        //每月利息
        Double interest=0.00;
        for (int i = 1; i <= months; i++) {
            RepaymentDetailVo repaymentDetailVo = new RepaymentDetailVo();
            repaymentDetailVo.setPeriods(i + "");
            repaymentDetailVo.setMonthlyCapital(monthPri.toString());
            //每月利息
            if(i==1){
                interest=firstMonth-monthPri;
            }else {
                interest=interest-decreaseMonth;
            }
            repaymentDetailVo.setMonthlyInterest(interest.toString());
            //每月还款总额=每月利息+本金
            Double monthly=Double.valueOf(repaymentDetailVo.getMonthlyCapital())+Double.valueOf(repaymentDetailVo.getMonthlyInterest());
            repaymentDetailVo.setMonthly(monthly.toString());
            totalCapital=totalCapital+monthPri;
            //总本金额减去已还款本金为剩余本金
            Double capitalBalance=money-totalCapital;
            repaymentDetailVo.setCapitalBalance(capitalBalance.toString());
            repaymentDetailVos.add(repaymentDetailVo);
        }
        //最后一条为总计
        RepaymentDetailVo rd = new RepaymentDetailVo();
        rd.setPeriods("总计");
        rd.setMonthlyCapital(money+"");
        rd.setMonthly(totalMoney.toString());
        rd.setMonthlyInterest(totalInterest.toString());
        rd.setCapitalBalance("---");
        repaymentDetailVos.add(rd);
    }

    /**
     * 等额本息还款【利息多】
     * @param money 贷款总额
     * @param rate  贷款商业利率
     * @param months 贷款月数
     */
    public static void interest(Double money, Double rate, Integer months,List<RepaymentDetailVo> repaymentDetailVos) {
        //月利率
        Double monthRate = resDoubleMonthRate(rate);
        //月还款本息(本金+利息)
        Double monthly = (money * monthRate * Math.pow((1 + monthRate), months)) / (Math.pow((1 + monthRate), months) - 1);
        //还款总额(本金+利息)
        Double totalMoney = monthly * months;
        //总利息
        Double totalInterest = totalMoney - money;
        //总计已还款本金
        Double totalCapital=0.00;
        for (int i = 1; i <= months; i++) {
            RepaymentDetailVo repaymentDetailVo = new RepaymentDetailVo();
            repaymentDetailVo.setPeriods(i + "");
            repaymentDetailVo.setMonthly(monthly.toString());
            //每月本金
            Double monthCapital = (money* monthRate.doubleValue() * (Math.pow((1+monthRate.doubleValue()),i-1)))/(Math.pow(1+monthRate.doubleValue(),months)-1);
            repaymentDetailVo.setMonthlyCapital(monthCapital.toString());
            //每月利息
            Double monthlyInterest=monthly-monthCapital;
            repaymentDetailVo.setMonthlyInterest(monthlyInterest.toString());
            //本金叠加
            totalCapital=totalCapital+Double.valueOf(repaymentDetailVo.getMonthlyCapital());
            //总本金额减去已还款本金为剩余本金
            Double capitalBalance=money-totalCapital;
            repaymentDetailVo.setCapitalBalance(capitalBalance.toString());
            repaymentDetailVos.add(repaymentDetailVo);
        }
        //最后一条为总计
        RepaymentDetailVo rd = new RepaymentDetailVo();
        rd.setPeriods("总计");
        rd.setMonthlyCapital(money+"");
        rd.setMonthly(totalMoney.toString());
        rd.setMonthlyInterest(totalInterest.toString());
        rd.setCapitalBalance("---");
        repaymentDetailVos.add(rd);
    }

    /**
     * 转换为月利率
     * @param rate
     * @return
     */
    public static BigDecimal resBigDecimalMonthRate(Double rate) {
        return new BigDecimal(rate).divide(new BigDecimal("12"),6,BigDecimal.ROUND_HALF_UP).divide(new BigDecimal("100")).setScale(6,BigDecimal.ROUND_HALF_UP);
    }
    public static Double resDoubleMonthRate(Double rate) {
        return rate / (100 * 12);
    }
}
package org.com.rsmall.db.vo;

import io.swagger.annotations.ApiModelProperty;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;

/**
 * @ClassName 还款明细
 * @Author yupanpan
 * @Date 2020/11/12 16:41
 */
@ToString
public class RepaymentDetailVo {

    @ApiModelProperty("期数")
    private String periods;

    @ApiModelProperty("月供")
    private String monthly;

    @ApiModelProperty("月供本金")
    private String monthlyCapital;

    @ApiModelProperty("月供利息")
    private String monthlyInterest;

    @ApiModelProperty("本金余额")
    private String capitalBalance;

    public String getPeriods() {
        return periods;
    }

    public void setPeriods(String periods) {
        this.periods = periods;
    }

    public String getMonthly() {
        return monthly;
    }

    public void setMonthly(String monthly) {
        this.monthly = new BigDecimal(monthly).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    public String getMonthlyCapital() {
        return monthlyCapital;
    }

    public void setMonthlyCapital(String monthlyCapital) {
        this.monthlyCapital = new BigDecimal(monthlyCapital).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    public String getMonthlyInterest() {
        return monthlyInterest;
    }

    public void setMonthlyInterest(String monthlyInterest) {
        this.monthlyInterest = new BigDecimal(monthlyInterest).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    public String getCapitalBalance() {
        return capitalBalance;
    }

    public void setCapitalBalance(String capitalBalance) {
        if (StringUtils.isNotBlank(capitalBalance)) {
            if (capitalBalance.equals("---")) {
                this.capitalBalance = capitalBalance;
            } else {
                if (BigDecimal.ZERO.compareTo(new BigDecimal(capitalBalance)) == 1) {
                    capitalBalance = "0.00";
                }
                this.capitalBalance = new BigDecimal(capitalBalance).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
            }
        } else {
            if (BigDecimal.ZERO.compareTo(new BigDecimal(capitalBalance)) == 1) {
                capitalBalance = "0.00";
            }
            this.capitalBalance = new BigDecimal(capitalBalance).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
        }
    }
}

最后的测试结果

和银行的结果全部一致(以下取自招行的计算结果)

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中处理银行还款功能,通常会涉及到以下几个步骤和思路: 1. **用户输入验证**:首先,接收用户的还款信息,如贷款金额、利率、还款期限等,并进行数据有效性检查,例如确认输入的是数值,日期在有效范围内。 ```java Scanner scanner = new Scanner(System.in); double loanAmount = scanner.nextDouble(); // ... 其他验证 ``` 2. **计算利息**:根据给定的信息(包括利率和时间)计算应支付的利息。这可能涉及复利公式或其他财务计算方法。 ```java double interestRate = scanner.nextDouble(); // 假设年利率 int yearsToPayback = scanner.nextInt(); double annualInterest = interestRate / 100; double totalInterest = loanAmount * annualInterest * yearsToPayback; ``` 3. **还款计划生成**:将总还款额分解到每个月或每个时间段,通常加上本金,形成还款列表。 ```java double monthlyPayment = (loanAmount + totalInterest) / yearsToPayback * 12; // 平均每月还款额 List<Double> paymentSchedule = new ArrayList<>(); for (int month = 1; month <= yearsToPayback * 12; month++) { double installment = (month == 1 ? loanAmount : monthlyPayment); // 初期可能包含部分本金 paymentSchedule.add(installment); } ``` 4. **记录和显示**:最后,保存还款计划至数据库,或打印出来供用户查看。 ```java // 假设有BankRepaymentRepository接口用于存储 bankRepaymentRepository.save(new BankRepayment(loanAmount, paymentSchedule)); // 或者简单地打印 System.out.println("月还款计划: " + paymentSchedule); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值