zoukankan      html  css  js  c++  java
  • java 等额本金与等额本息与等本等息的计算工具类

    java 等额本金与等额本息与等本等息的计算工具类

    等本等息是指:每月的本金相等,利息也相等

    等额本息是指:每月的本金+利息之和相等(其实每个月本金和利息都有变化,并不相等)

    本金是指:每月的本金相等,利息不等

    等额本金计算:

    等额本金是指一种贷款的还款方式,是在还款期内把贷款数总额等分,每月偿还同等数额的本金和剩余贷款在该月所产生的利息,这样由于每月的还款本金额固定,
     而利息越来越少,借款人起初还款压力较大,但是随时间的推移每月还款数也越来越少。

      1 package com.utils;
      2 
      3 import java.math.BigDecimal;
      4 import java.util.ArrayList;
      5 import java.util.HashMap;
      6 import java.util.List;
      7 import java.util.Map;
      8 import java.util.Map.Entry;
      9 
     10 /**
     11  * 等额本金是指一种贷款的还款方式,是在还款期内把贷款数总额等分,每月偿还同等数额的本金和剩余贷款在该月所产生的利息,这样由于每月的还款本金额固定,
     12  * 而利息越来越少,借款人起初还款压力较大,但是随时间的推移每月还款数也越来越少。
     13  */
     14 public class AverageCapitalUtils {
     15     
     16     private static final Integer month = 12;
     17 
     18     /**
     19      * 等额本金计算获取还款方式为等额本金的每月偿还本金和利息 (返回,期数,月总和。月利息,月本金)
     20      * 
     21      * 公式:每月偿还本金=(贷款本金÷还款月数)+(贷款本金-已归还本金累计额)×月利率
     22      * 
     23      * @param investMoney
     24      *            总借款额(贷款本金)
     25      * @param yearRate
     26      *            总年利率
     27      * @param otherRate
     28      *            加息年利率
     29      * @param unit
     30      *            單位:年,月
     31      * @param month
     32      *            还款总月数
     33      * @return 每月偿还本金和利息,不四舍五入,直接截取小数点最后两位
     34      */
     35     public static List<Map<String, Object>> getPerMonthPrincipalInterest(BigDecimal investMoney, BigDecimal yearRate,BigDecimal otherRate, int totalMonth) {
     36         
     37         yearRate = yearRate.divide(new BigDecimal("100"), 6, BigDecimal.ROUND_DOWN);//年利率
     38         
     39         List<Map<String, Object>> mapList = new ArrayList<>();
     40         Map<String, Object> map = null;
     41         BigDecimal totalAmount = BigDecimal.ZERO; //已还本息
     42         // 每月本金
     43         BigDecimal monthPri = getPerMonthPrincipal(investMoney, totalMonth);
     44         // 获取总月利率
     45         BigDecimal monthRate = yearRate.divide(new BigDecimal(month),6, BigDecimal.ROUND_DOWN);//向下取6位
     46         
     47         // 获取加息部分月利率
     48         BigDecimal monthOtherRate = otherRate.divide(new BigDecimal(month),6, BigDecimal.ROUND_DOWN);//向下取6位
     49         
     50         for (int i = 1; i <= totalMonth; i++) {
     51             if (i == totalMonth)  //最后一个月的本金= 总金额-已还总金额
     52                 monthPri = investMoney.subtract(totalAmount);
     53             totalAmount = totalAmount.add(monthPri);
     54             
     55             // (贷款本金-已归还本金累计额)×月利率
     56             BigDecimal monthInvest = investMoney.subtract(monthPri.multiply(new BigDecimal(i-1))).multiply(monthRate); //每月回款的总利息
     57             BigDecimal monthOtherInvest = investMoney.subtract(monthPri.multiply(new BigDecimal(i-1))).multiply(monthOtherRate); //每月回款的财务支付利息
     58             
     59             //每月回款金额 = 月利息+月本金
     60             BigDecimal monthRes = monthInvest.add(monthPri).setScale(2, BigDecimal.ROUND_DOWN);
     61             map = new HashMap<>();
     62             map.put("periods", i);
     63             map.put("monthResAndPri", monthRes); //每月回款总额
     64             map.put("monthPri", monthPri); // 回款本金
     65             map.put("monthInvest", monthInvest.setScale(6, BigDecimal.ROUND_DOWN)); // 回款利息
     66             map.put("monthOtherInvest", monthOtherInvest.setScale(6, BigDecimal.ROUND_DOWN)); // 回款其他利息
     67             map.put("surplusMoney", investMoney.subtract(totalAmount)); // 剩余本金
     68             mapList.add(map);
     69         }
     70         return mapList;
     71     }
     72 
     73     /**
     74      * 等额本金计算获取还款方式为等额本金的每月偿还利息
     75      * 
     76      * 公式:每月应还利息=剩余本金×月利率=(贷款本金-已归还本金累计额)×月利率
     77      * 
     78      * @param invest
     79      *            总借款额(贷款本金)
     80      * @param yearRate
     81      *            年利率
     82      * @param month
     83      *            还款总月数
     84      * @return 每月偿还利息
     85      */
     86     public static Map<String, Object> getPerMonthInterest(BigDecimal invest, BigDecimal yearRate, int totalMonth) {
     87         Map<String, Object> inMap = new HashMap<String, Object>();
     88         List<Map<String, Object>> mapList = getPerMonthPrincipalInterest(invest, yearRate,BigDecimal.ZERO, totalMonth);
     89         for (Map<String, Object> map : mapList) {
     90             inMap.put(map.get("periods").toString(), map.get("monthInvest"));
     91         }
     92         return inMap;
     93     }
     94     
     95     /**
     96      * 等额本金计算获取还款方式为等额本金的每天偿还利息
     97      * 
     98      * 公式:每天应还利息 = 本金*月利率/起息当月天数
     99      * @param invest
    100      *            总借款额(贷款本金)
    101      * @param yearRate
    102      *            年利率
    103      * @param totalDay
    104      *            起息当月天数
    105      * @return 每天偿还利息
    106      */
    107     public static BigDecimal getPerMonthInterestByDay(BigDecimal invest, BigDecimal yearRate, int totalDay) {
    108 
    109         yearRate = yearRate.divide(new BigDecimal("100"), 6, BigDecimal.ROUND_DOWN);//年利率
    110         
    111         BigDecimal monthRate = yearRate.divide(new BigDecimal(month),6, BigDecimal.ROUND_DOWN);//向下取6位,获取月利率
    112         
    113         BigDecimal income = invest.multiply(monthRate).divide(new BigDecimal(totalDay),6, BigDecimal.ROUND_DOWN);
    114         
    115         return income.setScale(6, BigDecimal.ROUND_DOWN);
    116     }
    117 
    118     /**
    119      * 等额本金计算获取还款方式为等额本金的每月偿还本金(每月回款本金)
    120      * 
    121      * 公式:每月应还本金=贷款本金÷还款月数
    122      * 
    123      * @param invest
    124      *            总借款额(贷款本金)
    125      * @param yearRate
    126      *            年利率
    127      * @param month
    128      *            还款总月数
    129      * @return 每月偿还本金
    130      */
    131     private static BigDecimal getPerMonthPrincipal(BigDecimal invest, int totalMonth) {
    132         BigDecimal monthIncome = invest.divide(new BigDecimal(totalMonth), 2, BigDecimal.ROUND_DOWN);
    133         return monthIncome;
    134     }
    135 
    136     /**
    137      * 等额本金计算获取还款方式为等额本金的总利息
    138      * 
    139      * @param invest
    140      *            总借款额(贷款本金)
    141      * @param yearRate
    142      *            年利率
    143      * @param month
    144      *            还款总月数
    145      * @return 总利息
    146      */
    147     public static BigDecimal getInterestCount(BigDecimal invest, BigDecimal yearRate, int totalMonth) {
    148         BigDecimal count = new BigDecimal(0);
    149         Map<String, Object> mapInterest = getPerMonthInterest(invest, yearRate, totalMonth);
    150 
    151         for (Entry<String, Object> entry : mapInterest.entrySet()) {
    152             count = count.add((BigDecimal) entry.getValue());
    153         }
    154         return count;
    155     }
    156 
    157     /**
    158      * @param args
    159      */
    160     public static void main(String[] args) {
    161         BigDecimal invest = new BigDecimal(10000); // 本金
    162         int month = 12;
    163         BigDecimal yearRate = new BigDecimal("8"); // 年利率
    164         List<Map<String, Object>> getPerMonthPrincipalInterest = getPerMonthPrincipalInterest(invest, yearRate,BigDecimal.ZERO, month);
    165         System.out.println("等额本金---每月本息:" + getPerMonthPrincipalInterest);
    166         BigDecimal benjin = getPerMonthPrincipal(invest, month);
    167         System.out.println("等额本金---每月本金:" + benjin);
    168         Map<String, Object> mapInterest = getPerMonthInterest(invest, yearRate, month);
    169         System.out.println("等额本金---每月利息:" + mapInterest);
    170 
    171         BigDecimal count = getInterestCount(invest, yearRate, month);
    172         System.out.println("等额本金---总利息:" + count);
    173         
    174         System.out.println(getPerMonthInterestByDay(invest, yearRate, 31));
    175     }
    176     
    177 }

    等额本息计算:

    等额本息是指一种贷款的还款方式,是在还款期内,每月偿还同等数额的贷款(包括本金和利息),和等额本金是不一样的概念,虽然刚开始还款时每月还款额可能会低于等额本金还款方式,但是最终所还利息会高于等额本金还款方式,该方式经常被银行使用。

    每月还款数额计算公式如下:
    [贷款本金×月利率×(1+月利率)^还款月数]÷[(1+月利率)^还款月数-1]
    下面举例说明等额本息还款法,
    假定借款人从银行获得一笔20万元的个人住房贷款贷款期限20年,贷款年利率4.2%,每月还本付息。按照上述公式计算,每月应偿还本息和为1233.14元。
    上述结果只给出了每月应付的本息和,因此需要对这个本息和进行分解。仍以上例为基础,一个月为一期,第一期贷款余额20万元,应支付利息700元(200000×4.2%/12),支付本金533.14元,仍欠银行贷款199466.86元;第二期应支付利息(199466.86×4.2%/12)元。
     package com.util;
    
    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.LoanProductStageVo;
    import com.TimeUnits;
    
    /**
     * 本息计算器
     * @Description: 本息算法
     */
    public class PrincipalAndInterestEquals {
        /**
         * 调试
         * @param args
         */
        public static void main(String[] args) {
            int periods = 4;
            TimeUnits unit = TimeUnits.day;
            RoundingMode roundingMode = RoundingMode.UP;
            BigDecimal rate = new BigDecimal("0.12");
            BigDecimal money = new BigDecimal("10000");
            
    //        equalPI_stage(periods, rate, unit, money, roundingMode);
    //        System.out.println("每月本息和(等额本息):"+equalPI_everyMonthPrincipalAddInterset(periods, rate, TimeUnits.month, money, RoundingMode.UP));
    //        System.out.println("每月本息和:"+pEqualI_stage(periods, rate,unit, money, RoundingMode.UP));
    //        pEqualI_stageSumNum(15 ,periods, rate, unit, money, roundingMode);
    //        equalP_stage(periods, rate, money, roundingMode);
            
    //        List<LoanProductStageVo> stages = equalPI_stage(periods, rate, TimeUnits.month, money, RoundingMode.UP);
    //        for(int i = 0; i < stages.size(); i++) {
    //            System.out.println("------------" + (i+1) + "期");
    //            System.out.println("本金:" + stages.get(i).getPrincipal());
    //            System.out.println("利息:" + stages.get(i).getInterset());
    //        }
        }
        
        /**
         * 月转年,乘以12
         */
        private static final BigDecimal MONTH_YEAR = new BigDecimal("12");
        /**
         * 天转月,乘以30,一月按30天算
         */
        private static final BigDecimal DAY_MONTH = new BigDecimal("30");
    //    private static final BigDecimal DAY_YEWR = new BigDecimal("365");
        /**
         * 利率百分数转换
         */
        private static final BigDecimal RATE_CONVERT_PERCENT = new BigDecimal("100");
    
        ///-------------------------------等额本息
        /**
         * 等额本息 —— 计算每期还款本息和
         * <p>设贷款额为a,月利率为i,年利率为I,还款月数为n,每月还款额为b,还款利息总和为Y<br/>
         * 月均还款:b=a×i×(1+i)^n÷〔(1+i)^n-1〕</p>
         * @param periods 期数,单位:月
         * @param rate 年利率
         * @param unit 期数单位(目前仅支持年、月、日)
         * @param money 要分期的金额
         * @param roundingMode 小数位处理
         * @return 每期还款额,如单位年,则为每年还款额
         */
        public static BigDecimal equalPI_everyMonthPrincipalAddInterset(Integer periods, BigDecimal rate, TimeUnits unit, BigDecimal money, RoundingMode roundingMode) {
            rate = rate.divide(RATE_CONVERT_PERCENT, roundingMode).divide(MONTH_YEAR, roundingMode);//将年利率转换成月利率
            /*
             * 设贷款额为a,月利率为i,年利率为I,还款月数为n,每月还款额为b,还款利息总和为Y
             * 月均还款:b=a×i×(1+i)^n÷〔(1+i)^n-1〕
             */
            BigDecimal newrate = rate.add(new BigDecimal("1")).pow(periods);//1+月利率
            BigDecimal ch = newrate.subtract(new BigDecimal("1"));
            BigDecimal monthMoney = money.multiply(rate).multiply(newrate).divide(ch, 2, roundingMode);//每月还款本息和
            
    //        System.out.println("每月还款本息:"+monthMoney);
    //        System.out.println("通过每月还款本息计算的还款总和:"+monthMoney.multiply(new BigDecimal(stage.getPeriods())));
            if(TimeUnits.year == unit) {
                return money.multiply(MONTH_YEAR).setScale(2, roundingMode);
            } else if(TimeUnits.day == unit) {
                return money.divide(DAY_MONTH, 2, roundingMode);
            }
            return monthMoney;
        }
    
        /**
         * 等额本息 —— 计算各个月份的还款额(<font color='red'>仅支持月</font>)
         * <p>设贷款额为a,月利率为i,年利率为I,还款月数为n,每月还款额为b,还款利息总和为Y<br/>
         * 第n月还款利息为:(a×i-b)×(1+i)^(n-1)+b</p>
         * <p>未完成:单位为年和日的,间隔不是1的情况</p>
         * @param periods 分期数,单位:月
         * @param rate 年利率
         * @param unit 单位(<font color='red'>仅支持月</font>)
         * @param money 贷款总金额
         * @param roundingMode 小数位处理
         * @return
         */
        public static List<LoanProductStageVo> equalPI_stage(Integer periods, BigDecimal rate, TimeUnits unit, BigDecimal money, RoundingMode roundingMode) {
            rate = rate.divide(RATE_CONVERT_PERCENT, roundingMode).divide(MONTH_YEAR, roundingMode);//计算月利率
            /*
             * 设贷款额为a,月利率为i,年利率为I,还款月数为n,每月还款额为b,还款利息总和为Y
             * 第n月还款利息为:(a×i-b)×(1+i)^(n-1)+b
             */
            List<LoanProductStageVo> stageResult = new ArrayList<>();
            //BigDecimal principalAddInterset = equalPI_everyMonthPrincipalAddInterset(periods, rate, unit, money,roundingMode);
            BigDecimal principalAddInterset = equalPI_everyMonthPrincipalAddInterset(periods, rate, TimeUnits.month, money,roundingMode);
            
            BigDecimal totalLixi = new BigDecimal(0);//临时:利息总额
            BigDecimal totalBenjin = new BigDecimal(0);//临时:本金总额
            for(int i = 0; i < periods; i++) {
    //            System.out.println("
    --------" + (i+1) + "期");
                LoanProductStageVo stageVo = new LoanProductStageVo();
                stageVo.setPrincipalAddInterset(principalAddInterset);
                if(i + 1 == periods) {
                    //最后一期的计算,将计算中因小数位导致数据不对称的补充回来
                    stageVo.setInterset(principalAddInterset.multiply(new BigDecimal(periods)).subtract(money).subtract(totalLixi));
                    stageVo.setPrincipal(money.subtract(totalBenjin));
                } else {
                    BigDecimal currentMonthRate = rate.add(new BigDecimal(1)).pow(i);
                    BigDecimal interset = money.multiply(rate).subtract(principalAddInterset).multiply(currentMonthRate).add(principalAddInterset).setScale(2, roundingMode);
                    stageVo.setInterset(interset);
                    stageVo.setPrincipal(principalAddInterset.subtract(interset));
                }
                
                totalLixi = totalLixi.add(stageVo.getInterset());
                totalBenjin = totalBenjin.add(stageVo.getPrincipal());
                stageResult.add(stageVo);
            }
    //        System.out.println("还款利息总额:" + totalLixi);
    //        System.out.println("还款本金总额:" + totalBenjin);
            return stageResult;
        }
        
        /**
         * 等额本息 —— 按照公式计算第n期的信息
         * @param n 第n期
         * @param periods 分期数
         * @param rate 月利率
         * @param unit 单位(目前仅支持年、月)
         * @param money 总本金额
         * @param roundingMode 小数位取值方式
         * @return
         */
        public static LoanProductStageVo equalPI_stageAtNum(int n, int periods, BigDecimal rate, BigDecimal money, RoundingMode roundingMode) {
            if(n <= 0) {
                return null;
            }
            if(n > periods) {
                return null;
            }
            rate = rate.divide(RATE_CONVERT_PERCENT, roundingMode).divide(MONTH_YEAR, roundingMode);
            /*
             * 设贷款额为a,月利率为i,年利率为I,还款月数为n,每月还款额为b,还款利息总和为Y
             * 第n月还款利息为:(a×i-b)×(1+i)^(n-1)+b
             */
            LoanProductStageVo stageVo = new LoanProductStageVo();
            BigDecimal principalAddInterset = equalPI_everyMonthPrincipalAddInterset(periods, rate, TimeUnits.month, money,roundingMode);
            BigDecimal currentMonthRate = rate.add(new BigDecimal(1)).pow(n - 1);
            BigDecimal interset = money.multiply(rate).subtract(principalAddInterset).multiply(currentMonthRate).add(principalAddInterset).setScale(2, roundingMode);
            stageVo.setPrincipalAddInterset(principalAddInterset);
            stageVo.setInterset(interset);
            stageVo.setPrincipal(principalAddInterset.subtract(interset));
            return stageVo;
        }
        
        ///-------------------------------等额本金
        /**
         * 等额本息 —— 计算每期信息
         * <p>公式:每月还款金额 = (贷款本金 / 还款月数)+(本金 — 已归还本金累计额)×每月利率</p>
         *
         * @param periods 分期数
         * @param rate 年利率
         * @param money 本金总额
         * @param roundingMode 小数位处理
         * @return
         */
        public static List<LoanProductStageVo> equalP_stage(int periods, BigDecimal rate, BigDecimal money, RoundingMode roundingMode) {
            final BigDecimal PERIODS = new BigDecimal(periods + "");
            rate = rate.divide(RATE_CONVERT_PERCENT, roundingMode).divide(MONTH_YEAR, roundingMode);
            List<LoanProductStageVo> stageResult = new ArrayList<>();
            
            //每月还款本金
            BigDecimal everyMonthPrincipal = money.divide(PERIODS, 2, roundingMode);
            
            BigDecimal totalBenjin = new BigDecimal("0");
            BigDecimal totalLixi = new BigDecimal("0");
            for(int i = 0; i < periods; i++) {
    //            System.out.println("
    --------" + (i+1) + "期");
                LoanProductStageVo stageVo = new LoanProductStageVo();
                if(i+1 == periods) {
                    stageVo.setPrincipal(money.subtract(totalBenjin));
                    stageVo.setInterset(stageVo.getPrincipal().multiply(rate).setScale(2, roundingMode));
                } else {
                    stageVo.setPrincipal(everyMonthPrincipal);
                    stageVo.setInterset(money.subtract(totalBenjin).multiply(rate).setScale(2, roundingMode));
                }
                
    //            System.out.println("本金:"+stageVo.getPrincipal());
    //            System.out.println("利息:"+stageVo.getInterset());
                
                totalBenjin = totalBenjin.add(stageVo.getPrincipal());
                totalLixi = totalLixi.add(stageVo.getInterset());
                
                stageResult.add(stageVo);
            }
    //        System.out.println("本金和:"+totalBenjin);
    //        System.out.println("利息和:"+totalLixi);
            return stageResult;
        }
    }
    等本等息为民间借贷、分期购物、银行分期中的一种还款方式。
    月还款为:本金+利息。
    举例说明,假设借款额3万元,借款期限12个月,预计年化借款利率12%,等本等息还款,每月月末归还本金及利息,则公式如下:每月归还本金=贷款3万÷12期=2500元,预计年利息=3万×12%=3600元,为月息300元,那就是每个月需还2500+300=2800元。
    package com.zhonglian.jinju.pub.service.support;
    
    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.LoanProductStageVo;
    import com.TimeUnits;
    
    /**
     *等 本等息计算器
     * @Description: 本息算法
     */
    public class PrincipalAndInterestEquals2 {
        /**
         * 调试
         * @param args
         */
        public static void main(String[] args) {
            int periods = 4;
            TimeUnits unit = TimeUnits.day;
            RoundingMode roundingMode = RoundingMode.UP;
            BigDecimal rate = new BigDecimal("0.12");
            BigDecimal money = new BigDecimal("10000");
            
        pEqualI_stageSumNum(15 ,periods, rate, unit, money, roundingMode);
    //        equalP_stage(periods, rate, money, roundingMode);
            
    //        List<LoanProductStageVo> stages = equalPI_stage(periods, rate, TimeUnits.month, money, RoundingMode.UP);
    //        for(int i = 0; i < stages.size(); i++) {
    //            System.out.println("------------" + (i+1) + "期");
    //            System.out.println("本金:" + stages.get(i).getPrincipal());
    //            System.out.println("利息:" + stages.get(i).getInterset());
    //        }
        }
        
        /**
         * 月转年,乘以12
         */
        private static final BigDecimal MONTH_YEAR = new BigDecimal("12");
        /**
         * 天转月,乘以30,一月按30天算
         */
        private static final BigDecimal DAY_MONTH = new BigDecimal("30");
    //    private static final BigDecimal DAY_YEWR = new BigDecimal("365");
        /**
         * 利率百分数转换
         */
        private static final BigDecimal RATE_CONVERT_PERCENT = new BigDecimal("100");
    
        ///-------------------------------等本等息
        
        /**
         * 等本等息 —— 计算每期信息
         * <p>算法:第n月还款利息为:贷款总额 * 年利率 / 分期数</p>
         * @param periods 分期数,单位月
         * @param rate 利率
         * @param money 贷款总额
         * @param roundingMode 小数位处理
         * @return
         */
        public static List<LoanProductStageVo> pEqualI_stage(int periods, BigDecimal rate, BigDecimal money, RoundingMode roundingMode) {
            rate = rate.divide(RATE_CONVERT_PERCENT, roundingMode);
            List<LoanProductStageVo> result = new ArrayList<>();
            BigDecimal everyMonthPrincipal = money.divide(new BigDecimal(periods+""), 2, roundingMode);
            BigDecimal everyMonthInterset = money.multiply(rate).divide(MONTH_YEAR, roundingMode);
            BigDecimal totalInterset = everyMonthInterset.multiply(new BigDecimal(periods+""));
            BigDecimal principalAddInterset = everyMonthPrincipal.add(everyMonthInterset);
            
            BigDecimal totalBenjin = new BigDecimal("0");
            BigDecimal totalLixi = new BigDecimal("0");
            for(int i = 0; i < periods; i++) {
    //            System.out.println("
    --------" + (i+1) + "期");
                LoanProductStageVo stageVo = new LoanProductStageVo();
                if(i + 1 == periods) {
                    //TODO 算法疑问:最后一期会与前面的不一样
    //                System.out.println("最后");
                    stageVo.setPrincipal(money.subtract(totalBenjin));
                    stageVo.setInterset(totalInterset.subtract(totalLixi).setScale(2, roundingMode));
                    stageVo.setPrincipalAddInterset(principalAddInterset);
                } else {
                    stageVo.setInterset(everyMonthInterset);
                    stageVo.setPrincipal(everyMonthPrincipal);
                    stageVo.setPrincipalAddInterset(principalAddInterset);
                }
                result.add(stageVo);
                
                totalBenjin = totalBenjin.add(stageVo.getPrincipal());
                totalLixi = totalLixi.add(stageVo.getInterset());
                
    //            System.out.println("本金:"+stageVo.getPrincipal());
    //            System.out.println("利息:"+stageVo.getInterset());
    //            System.out.println("月本息和:"+stageVo.getPrincipalAddInterset());
            }
    //        System.out.println("本金和:"+totalBenjin);
    //        System.out.println("利息和:"+totalLixi);
            
            return result;
        }
    
        /**
         * 等本等息 —— 计算前n期之和,时间单位支持年、月、日(按照公式计算)
         * <br/>但对最后一期本金或利息不会“多退少补”计算,本方法完全按照公式走
         * @param n 要计算的期数,单位:月
         * @param periods 分期数
         * @param rate 年利率
         * @param unit 时间单位
         * @param money 总金额
         * @param roundingMode 小数位取值方式
         * @return 如果要获取的期数超过分期期数,则返回总本息信息
         */
        public static LoanProductStageVo pEqualI_stageSumNum(int n, int periods, BigDecimal rate, TimeUnits unit, BigDecimal money, RoundingMode roundingMode) {
            rate = rate.divide(RATE_CONVERT_PERCENT, roundingMode);
            LoanProductStageVo stageVo = new LoanProductStageVo();
            if(n <= 0) {
                stageVo.setInterset(new BigDecimal("0"));
                stageVo.setPrincipal(new BigDecimal("0"));
                return stageVo;
            }
            final BigDecimal PERIODS = new BigDecimal(periods+"");
            final BigDecimal N = new BigDecimal(n + "");
            BigDecimal monthPrincipal = money.divide(PERIODS, 2, roundingMode);//月本金
            BigDecimal monthInterset = money.multiply(rate).divide(MONTH_YEAR, 2, roundingMode);//月利息
            BigDecimal nSumPrincipal = null, nSumInterset = null;
            boolean nEp = true;//期数校验
            if(TimeUnits.year == unit) {
                if(n * 12 <= periods) {
                    nSumPrincipal = monthPrincipal.multiply(N).multiply(MONTH_YEAR);
                    nSumInterset = monthInterset.multiply(N).multiply(MONTH_YEAR);
                    nEp = false;
                }
            } else if(TimeUnits.month == unit) {
                if(n <= periods) {
                    nSumPrincipal = monthPrincipal.multiply(N);
                    nSumInterset = monthInterset.multiply(N);
                    nEp = false;
                }
            } else if(TimeUnits.day == unit) {
                if(n / 30 <= periods) {
                    nSumPrincipal = monthPrincipal.multiply(N).divide(DAY_MONTH, 2, roundingMode);
                    nSumInterset = monthInterset.multiply(N).divide(DAY_MONTH, 2, roundingMode);
                    nEp = false;
                }
            } else {
                return null;
            }
            //n的时间大于分期数情况,计算总和
            if(nEp) {
                nSumPrincipal = monthPrincipal.multiply(PERIODS);
                nSumInterset = monthInterset.multiply(PERIODS);
            }
            stageVo.setPrincipal(nSumPrincipal);
            stageVo.setInterset(nSumInterset);
            
    //        System.out.println("等本等息:前"+n+unit.getText()+"信息");
    //        System.out.println("本金和:"+stageVo.getPrincipal());
    //        System.out.println("利息和:"+stageVo.getInterset());
            
            return stageVo;
        }
        
        
    }

    TimeUnits类

    package com.enums;
    
    import com.fasterxml.jackson.databind.annotation.JsonSerialize;
    
    @JsonSerialize(as = StringValueTextEnum.class)
    public enum TimeUnits implements StringValueTextEnum {
    
        /***/
        minute("minute", "分"),
    
        /***/
        hour("hour", "时"),
    
        /***/
        day("day", "天"),
    
        /***/
        week("week", "周"),
    
        /***/
        month("month", "月"),
    
        /***/
        year("year", "年");
    
        private String value;
        private String text;
    
        private TimeUnits(String value, String text) {
            this.value = value;
            this.text = text;
        }
    
        public String getValue() {
            return value;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    
        public String getText() {
            return text;
        }
    
        public void setText(String text) {
            this.text = text;
        }
    
    }

     LoanProductStageVo公共类

    package com.bo;
    
    import java.math.BigDecimal;
    
    /**
     * 分期计算结果类
     *
     */
    public class LoanProductStageVo {
        //本息和
        private BigDecimal principalAddInterset;
        //本金
        private BigDecimal principal;
        //利息
        private BigDecimal interset;
        
        /**
         * 本息和(单独的公式计算,每月相同)
         * @return
         */
        public BigDecimal getPrincipalAddInterset() {
            if(principalAddInterset == null && principal != null && interset != null) {
                principalAddInterset = principal.add(interset);
            }
            return principalAddInterset;
        }
        /**
         * 本息和(单独的公式计算,每月相同)
         * @param principalAddInterset
         */
        public void setPrincipalAddInterset(BigDecimal principalAddInterset) {
            this.principalAddInterset = principalAddInterset;
        }
        /**
         * 本金
         * @return
         */
        public BigDecimal getPrincipal() {
            return principal;
        }
        /**
         * 本金
         * @param principal
         */
        public void setPrincipal(BigDecimal principal) {
            this.principal = principal;
        }
        /**
         * 利息
         * @return
         */
        public BigDecimal getInterset() {
            return interset;
        }
        /**
         * 利息
         * @param interset
         */
        public void setInterset(BigDecimal interset) {
            this.interset = interset;
        }
    }

     试试哪种最划算吧!!

    爱生活,更爱给我带来生活的人
  • 相关阅读:
    Leetcode题目322.零钱兑换(动态规划-中等)
    Leetcode题目292.Nim游戏(脑筋急转弯)
    Leetcode题目300.最长上升子序列(动态规划-中等)
    Leetcode题目287.寻找重复数(中等)
    Android学习笔记---初识eventbus
    Android学习笔记----实现卡牌翻转动画
    Android学习笔记----在Android使用ping来检测网络是否可用
    Android学习笔记----初体验ButterKnife框架
    Android 学习笔记---使用shell命令来关闭和开启ADB
    Android学习笔记--客户端上传图片到PHP服务器(带PHP端代码)
  • 原文地址:https://www.cnblogs.com/chenyq/p/6297214.html
Copyright © 2011-2022 走看看