Java 双指针在实际项目中的应用

背景说明

最近在做财务相关的系统,对账单核销预付款
从技术角度来看就是将两个数组进行合并

对账单核销预付款前提条件:

  1. 对账单总金额必须等于未核销金额

数据示例

对账单数据

单号 金额
B0001 100
B0002 80
B0003 120

预付款数据

单号 未核销金额
PRE001 110
PRE002 190

结果数据

预付款单号 核销金额 对账单号
PRE001 100 B001
PRE001 10 B002
PRE002 70 B002
PRE002 120 B003

通过分析可以使用JAVA双指针算法可以实现这个需求
双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。

代码实现

public static void main(String[] args) {
    class Info {
        private String formId;
        private BigDecimal amount;
    
        public String getFormId() {
            return formId;
        }
    
        public void setFormId(String formId) {
            this.formId = formId;
        }
    
        public BigDecimal getAmount() {
            return amount;
        }
    
        public void setAmount(BigDecimal amount) {
            this.amount = amount;
        }
    }
    
    List<Info> billBatchlist = new ArrayList<>();
    Info info = new Info();
    info.setFormId("B0001");
    info.setAmount(new BigDecimal(100));
    billBatchlist.add(info);
    info = new Info();
    info.setFormId("B0002");
    info.setAmount(new BigDecimal(80));
    billBatchlist.add(info);
    info = new Info();
    info.setFormId("B0003");
    info.setAmount(new BigDecimal(120));
    billBatchlist.add(info);
    
    List<Info> payVerifyControlList = new ArrayList<>();
    Info info1 = new Info();
    info1.setFormId("PRE0001");
    info1.setAmount(new BigDecimal(110));
    payVerifyControlList.add(info1);
    info1 = new Info();
    info1.setFormId("PRE0002");
    info1.setAmount(new BigDecimal(190));
    payVerifyControlList.add(info1);
    billBatchlist.forEach(a -> {
        System.out.println("BillFormId:" + a.formId + ",Amount:" + a.getAmount());
    });
    payVerifyControlList.forEach(a -> {
        System.out.println("PreFormId:" + a.formId + ",Amount:" + a.getAmount());
    });
    System.out.println("==================================");
    
    int i = 0, j = 0;
    BigDecimal preAmount = new BigDecimal(0);
    BigDecimal billAmount = new BigDecimal(0);
    while (i < billBatchlist.size() && j < payVerifyControlList.size()) {
        if (preAmount.compareTo(BigDecimal.ZERO) == 0) {
            preAmount = billBatchlist.get(i).amount;
        }
        if (billAmount.compareTo(BigDecimal.ZERO) == 0) {
            billAmount = payVerifyControlList.get(j).amount;
        }
    
        //当前核销金额
        BigDecimal verifyAmount = new BigDecimal(0);
        if (preAmount.compareTo(billAmount) > -1) {
            verifyAmount = billAmount;
            // pre剩余
            preAmount = preAmount.subtract(verifyAmount);
            billAmount = new BigDecimal(0);
        } else {
            verifyAmount = preAmount;
            // bill剩余
            billAmount = billAmount.subtract(verifyAmount);
            preAmount = new BigDecimal(0);
        }
    
        System.out.println("当前核销金额:" + verifyAmount + ",preAmount剩余:" + preAmount + ",billAmount剩余:" + billAmount);
        //大于等于0
        if (preAmount.compareTo(BigDecimal.ZERO) == 0) {
            i++;
        }
        if (billAmount.compareTo(BigDecimal.ZERO) == 0) {
            j++;
        }
    }
    }

打印结果:

BillFormId:B0001,Amount:100
BillFormId:B0002,Amount:80
BillFormId:B0003,Amount:120
PreFormId:PRE0001,Amount:110
PreFormId:PRE0002,Amount:190
==================================
当前核销金额:100,preAmount剩余:0,billAmount剩余:10
当前核销金额:10,preAmount剩余:70,billAmount剩余:0
当前核销金额:70,preAmount剩余:0,billAmount剩余:120
当前核销金额:120,preAmount剩余:0,billAmount剩余:0