房贷计算算法

/**
 * Description:等额本金工具类
 */

import com.google.common.collect.Maps;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

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

    /**
     * 等额本金计算获取还款方式为等额本金的每月偿还本金和利息
     *
     * 公式:每月偿还本金=(贷款本金÷还款月数)+(贷款本金-已归还本金累计额)×月利率
     *
     * @param invest
     *            总借款额(贷款本金)
     * @param yearRate
     *            年利率
     * @param month
     *            还款总月数
     * @return 每月偿还本金和利息,不四舍五入,直接截取小数点最后两位
     */
    public static Map<Integer, Double> getPerMonthPrincipalInterest(double invest, double yearRate, int totalMonth) {
        Map<Integer, Double> map = new HashMap<Integer, Double>();
        // 每月本金
        double monthPri = getPerMonthPrincipal(invest, totalMonth);
        // 获取月利率
        double monthRate = yearRate / 12;
        monthRate = new BigDecimal(monthRate).setScale(6, BigDecimal.ROUND_DOWN).doubleValue();
        for (int i = 1; i <= totalMonth; i++) {
            double monthRes = monthPri + (invest - monthPri * (i - 1)) * monthRate;
            monthRes = new BigDecimal(monthRes).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
            map.put(i, monthRes);
        }
        return map;
    }
    /**
     * 等额本金计算获取还款方式为等额本金的每月偿还利息
     *
     * 公式:每月应还利息=剩余本金×月利率=(贷款本金-已归还本金累计额)×月利率
     *
     * @param invest
     *            总借款额(贷款本金)
     * @param yearRate
     *            年利率
     * @param month
     *            还款总月数
     * @return 每月偿还利息
     */
    public static Map<Integer, Double> getPerMonthInterest(double invest, double yearRate, int totalMonth) {
        Map<Integer, Double> inMap = new HashMap<Integer, Double>();
        double principal = getPerMonthPrincipal(invest, totalMonth);
        Map<Integer, Double> map = getPerMonthPrincipalInterest(invest, yearRate, totalMonth);
        for (Map.Entry<Integer, Double> entry : map.entrySet()) {
            BigDecimal principalBigDecimal = new BigDecimal(principal);
            BigDecimal principalInterestBigDecimal = new BigDecimal(entry.getValue());
            BigDecimal interestBigDecimal = principalInterestBigDecimal.subtract(principalBigDecimal);
            interestBigDecimal = interestBigDecimal.setScale(2, BigDecimal.ROUND_DOWN);
            inMap.put(entry.getKey(), interestBigDecimal.doubleValue());
        }
        return inMap;
    }

    /**
     * 等额本金计算获取还款方式为等额本金的每月偿还本金
     *
     * 公式:每月应还本金=贷款本金÷还款月数
     *
     * @param invest
     *            总借款额(贷款本金)
     * @param yearRate
     *            年利率
     * @param month
     *            还款总月数
     * @return 每月偿还本金
     */
    public static double getPerMonthPrincipal(double invest, int totalMonth) {
        BigDecimal monthIncome = new BigDecimal(invest).divide(new BigDecimal(totalMonth), 2, BigDecimal.ROUND_DOWN);
        return monthIncome.doubleValue();
    }

    /**
     * 等额本金计算获取还款方式为等额本金的总利息
     *
     * @param invest
     *            总借款额(贷款本金)
     * @param yearRate
     *            年利率
     * @param month
     *            还款总月数
     * @return 总利息
     */
    public static double getInterestCount(double invest, double yearRate, int totalMonth) {
        BigDecimal count = new BigDecimal(0);
        Map<Integer, Double> mapInterest = getPerMonthInterest(invest, yearRate, totalMonth);

        for (Map.Entry<Integer, Double> entry : mapInterest.entrySet()) {
            count = count.add(new BigDecimal(entry.getValue()));
        }
        return count.doubleValue();
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        double invest = 800000; // 本金
        int month = 120;
        double yearRate = 0.052; // 年利率
        Map<Integer, Double> getPerMonthPrincipalInterest = getPerMonthPrincipalInterest(invest, yearRate, month);
        System.out.println("等额本金---每月本息:" + getPerMonthPrincipalInterest);

        double benjin = getPerMonthPrincipal(invest, month);
        System.out.println("等额本金---每月本金:" + benjin);

        Map<Integer, Double> mapInterest = getPerMonthInterest(invest, yearRate, month);
        System.out.println("等额本金---每月利息:" + mapInterest);

        Map<Integer, Double> mapInterestCount = Maps.newHashMap();
        for(Map.Entry<Integer, Double> entry : mapInterest.entrySet()){
            int curMonth = entry.getKey();
            Double curIntersetCount = 0d;
            if(curMonth > 1){
                curIntersetCount = entry.getValue() + mapInterestCount.get(curMonth - 1);
            }else {
                curIntersetCount = entry.getValue();
            }
            Double value = new BigDecimal(String.valueOf(curIntersetCount)).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
            mapInterestCount.put(curMonth, value);
        }
        System.out.println("等额本金---各月加和:" + mapInterestCount);

        double count = getInterestCount(invest, yearRate, month);
        System.out.println("等额本金---总利息:" + count);
    }
}
import com.google.common.collect.Maps;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class AverageCapitalPlusInterestUtils {

    /**
     * 等额本息计算获取还款方式为等额本息的每月偿还本金和利息
     * <p>
     * 公式:每月偿还本息=〔贷款本金×月利率×(1+月利率)^还款月数〕÷〔(1+月利率)^还款月数-1〕
     *
     * @param invest   总借款额(贷款本金)
     * @param yearRate 年利率
     * @param month    还款总月数
     * @return 每月偿还本金和利息, 不四舍五入,直接截取小数点最后两位
     */
    public static double getPerMonthPrincipalInterest(double invest, double yearRate, int totalmonth) {
        double monthRate = yearRate / 12;
        BigDecimal monthIncome = new BigDecimal(invest)
                .multiply(new BigDecimal(monthRate * Math.pow(1 + monthRate, totalmonth)))
                .divide(new BigDecimal(Math.pow(1 + monthRate, totalmonth) - 1), 2, BigDecimal.ROUND_DOWN);
        return monthIncome.doubleValue();
    }

    /**
     * 等额本息计算获取还款方式为等额本息的每月偿还利息
     * <p>
     * 公式:每月偿还利息=贷款本金×月利率×〔(1+月利率)^还款月数-(1+月利率)^(还款月序号-1)〕÷〔(1+月利率)^还款月数-1〕
     *
     * @param invest   总借款额(贷款本金)
     * @param yearRate 年利率
     * @param month    还款总月数
     * @return 每月偿还利息
     */
    public static Map<Integer, BigDecimal> getPerMonthInterest(double invest, double yearRate, int totalmonth) {
        Map<Integer, BigDecimal> map = new HashMap<Integer, BigDecimal>();
        double monthRate = yearRate / 12;
        BigDecimal monthInterest;
        for (int i = 1; i < totalmonth + 1; i++) {
            BigDecimal multiply = new BigDecimal(invest).multiply(new BigDecimal(monthRate));
            BigDecimal sub = new BigDecimal(Math.pow(1 + monthRate, totalmonth)).subtract(new BigDecimal(Math.pow(1 + monthRate, i - 1)));
            monthInterest = multiply.multiply(sub).divide(new BigDecimal(Math.pow(1 + monthRate, totalmonth) - 1), 6, BigDecimal.ROUND_DOWN);
            monthInterest = monthInterest.setScale(2, BigDecimal.ROUND_DOWN);
            map.put(i, monthInterest);
        }
        return map;
    }

    /**
     * 等额本息计算获取还款方式为等额本息的每月偿还本金
     *
     * @param invest   总借款额(贷款本金)
     * @param yearRate 年利率
     * @param month    还款总月数
     * @return 每月偿还本金
     */
    public static Map<Integer, BigDecimal> getPerMonthPrincipal(double invest, double yearRate, int totalmonth) {
        double monthRate = yearRate / 12;
        BigDecimal monthIncome = new BigDecimal(invest)
                .multiply(new BigDecimal(monthRate * Math.pow(1 + monthRate, totalmonth)))
                .divide(new BigDecimal(Math.pow(1 + monthRate, totalmonth) - 1), 2, BigDecimal.ROUND_DOWN);
        Map<Integer, BigDecimal> mapInterest = getPerMonthInterest(invest, yearRate, totalmonth);
        Map<Integer, BigDecimal> mapPrincipal = new HashMap<Integer, BigDecimal>();

        for (Map.Entry<Integer, BigDecimal> entry : mapInterest.entrySet()) {
            mapPrincipal.put(entry.getKey(), monthIncome.subtract(entry.getValue()));
        }
        return mapPrincipal;
    }

    /**
     * 等额本息计算获取还款方式为等额本息的总利息
     *
     * @param invest   总借款额(贷款本金)
     * @param yearRate 年利率
     * @param month    还款总月数
     * @return 总利息
     */
    public static double getInterestCount(double invest, double yearRate, int totalmonth) {
        BigDecimal count = new BigDecimal(0);
        Map<Integer, BigDecimal> mapInterest = getPerMonthInterest(invest, yearRate, totalmonth);

        for (Map.Entry<Integer, BigDecimal> entry : mapInterest.entrySet()) {
            count = count.add(entry.getValue());
        }
        return count.doubleValue();
    }

    /**
     * 应还本金总和
     *
     * @param invest   总借款额(贷款本金)
     * @param yearRate 年利率
     * @param month    还款总月数
     * @return 应还本金总和
     */
    public static double getPrincipalInterestCount(double invest, double yearRate, int totalmonth) {
        double monthRate = yearRate / 12;
        BigDecimal perMonthInterest = new BigDecimal(invest)
                .multiply(new BigDecimal(monthRate * Math.pow(1 + monthRate, totalmonth)))
                .divide(new BigDecimal(Math.pow(1 + monthRate, totalmonth) - 1), 2, BigDecimal.ROUND_DOWN);
        BigDecimal count = perMonthInterest.multiply(new BigDecimal(totalmonth));
        count = count.setScale(2, BigDecimal.ROUND_DOWN);
        return count.doubleValue();
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        double invest = 800000; // 本金
        int month = 120;
        double yearRate = 0.052; // 年利率
        double perMonthPrincipalInterest = getPerMonthPrincipalInterest(invest, yearRate, month);
        System.out.println("等额本息---每月还款本息:" + perMonthPrincipalInterest);


        Map<Integer, BigDecimal> mapInterest = getPerMonthInterest(invest, yearRate, month);
        System.out.println("等额本息---每月还款利息:" + mapInterest);
        Map<Integer, BigDecimal> mapInterestCount = Maps.newHashMap();
        for(Map.Entry<Integer, BigDecimal> entry : mapInterest.entrySet()){
            int curMonth = entry.getKey();
            BigDecimal curIntersetCount = new BigDecimal(0);
            if(curMonth > 1){
                curIntersetCount = entry.getValue().add(mapInterestCount.get(curMonth - 1));
            }else {
                curIntersetCount = entry.getValue();
            }
            mapInterestCount.put(curMonth, curIntersetCount);
        }
        System.out.println("等额本金---各月加和:" + mapInterestCount);

        Map<Integer, BigDecimal> mapPrincipal = getPerMonthPrincipal(invest, yearRate, month);
        System.out.println("等额本息---每月还款本金:" + mapPrincipal);


        double count = getInterestCount(invest, yearRate, month);
        System.out.println("等额本息---总利息:" + count);


        double principalInterestCount = getPrincipalInterestCount(invest, yearRate, month);
        System.out.println("等额本息---应还本息总和:" + principalInterestCount);
    }
}

import com.google.common.collect.Maps;

import java.math.BigDecimal;
import java.util.Map;

/**
 * 提前还贷款:http://www.zuhedaikuan.com/jsq/tiqian.aspx
 */
public class House {
    public static void main(String[] args) {
        testHose(580000, 0.052, 60);
        System.out.println();
        System.out.println();
        System.out.println();
        testHose(500000, 0.0325, 120);
    }

    public static void testHose(double invest, double yearRate, int month){

        Map<Integer, Double> getPerMonthPrincipalInterest = AverageCapitalUtils.getPerMonthPrincipalInterest(invest, yearRate, month);
        System.out.println("等额本金---每月本息:" + getPerMonthPrincipalInterest);
        double perMonthPrincipalInterestPlus = AverageCapitalPlusInterestUtils.getPerMonthPrincipalInterest(invest, yearRate, month);
        System.out.println("等额本息---每月本息:" + perMonthPrincipalInterestPlus);
        System.out.println();


        double benjin = AverageCapitalUtils.getPerMonthPrincipal(invest, month);
        System.out.println("等额本金---每月本金:" + benjin);
        Map<Integer, BigDecimal> mapPrincipalPlus = AverageCapitalPlusInterestUtils.getPerMonthPrincipal(invest, yearRate, month);
        System.out.println("等额本息---每月本金:" + mapPrincipalPlus);
        System.out.println();


        double benjinMonth = AverageCapitalUtils.getPerMonthPrincipal(invest, month);
        Map<Integer, BigDecimal> benjinAll = Maps.newHashMap();
        for(int i=0; i<month ;i++){
            if(i == 0){
                benjinAll.put(i + 1, new BigDecimal(String.valueOf(benjinMonth)));
            }else {
                benjinAll.put(i + 1, benjinAll.get(i).add(new BigDecimal(String.valueOf(benjinMonth))));
            }
        }
        System.out.println("等额本金---已还本金:" + benjinAll);
        Map<Integer, BigDecimal> mapPrincipalAll = Maps.newHashMap();
        for(Map.Entry<Integer, BigDecimal> entry : AverageCapitalPlusInterestUtils.getPerMonthPrincipal(invest, yearRate, month).entrySet()) {
            int curMonth = entry.getKey();
            BigDecimal curIntersetCount = new BigDecimal(0);
            if(curMonth > 1){
                curIntersetCount = entry.getValue().add(mapPrincipalAll.get(curMonth - 1));
            }else {
                curIntersetCount = entry.getValue();
            }
            mapPrincipalAll.put(curMonth, curIntersetCount);
        }
        System.out.println("等额本息---已还本金:" + mapPrincipalAll);
        System.out.println();


        Map<Integer, Double> mapInterest = AverageCapitalUtils.getPerMonthInterest(invest, yearRate, month);
        System.out.println("等额本金---每月利息:" + mapInterest);
        Map<Integer, BigDecimal> mapInterestPlus = AverageCapitalPlusInterestUtils.getPerMonthInterest(invest, yearRate, month);
        System.out.println("等额本息---每月利息:" + mapInterestPlus);
        System.out.println();

        Map<Integer, Double> mapInterestCount = Maps.newHashMap();
        for(Map.Entry<Integer, Double> entry : mapInterest.entrySet()){
            int curMonth = entry.getKey();
            Double curIntersetCount = 0d;
            if(curMonth > 1){
                curIntersetCount = entry.getValue() + mapInterestCount.get(curMonth - 1);
            }else {
                curIntersetCount = entry.getValue();
            }
            Double value = new BigDecimal(String.valueOf(curIntersetCount)).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
            mapInterestCount.put(curMonth, value);
        }
        System.out.println("等额本金---各月加和:" + mapInterestCount);
        Map<Integer, BigDecimal> mapInterestCountPlus = Maps.newHashMap();
        for(Map.Entry<Integer, BigDecimal> entry : mapInterestPlus.entrySet()){
            int curMonth = entry.getKey();
            BigDecimal curIntersetCountPlus = new BigDecimal(0);
            if(curMonth > 1){
                curIntersetCountPlus = entry.getValue().add(mapInterestCountPlus.get(curMonth - 1));
            }else {
                curIntersetCountPlus = entry.getValue();
            }
            mapInterestCountPlus.put(curMonth, curIntersetCountPlus);
        }
        System.out.println("等额本金---各月加和:" + mapInterestCountPlus);
        System.out.println();


        double beforecount = AverageCapitalUtils.getInterestCount(invest, yearRate, month);
        System.out.println("等额本金---总利息:" + beforecount);
        double beforecountPlus = AverageCapitalPlusInterestUtils.getInterestCount(invest, yearRate, month);
        System.out.println("等额本息---总利息:" + beforecountPlus);
    }
}

Guess you like

Origin blog.csdn.net/maoyeqiu/article/details/120689530
Recommended