Java函数式编程消除if-else

435 阅读1分钟

Java函数式编程消除if-else

前言

有个朋友问我,if-else怎么删除,看着很烦。

List<String> DepositAccList = new ArrayList<>();
String baseAccnum = "";
String baseAccnumFlag = "0";
String baseAccnumFlag2 = "0";
String linkBankNum = "";
for (DepositBankAccInfo depositBankAccInfo : bankAccInfoReadList) {
    if (depositBankAccInfo.getAccountUsageType().equals("09")) {
        baseAccnum = depositBankAccInfo.getUnitPaymentAccnum();
    }
    if (depositBankAccInfo.getAccountUsageType().equals("09") || depositBankAccInfo.getAccountUsageType().equals("01")) {
        baseAccnumFlag = "1";
        linkBankNum = depositBankAccInfo.getLinkBankNum();
    }
    if (depositBankAccInfo.getAccountUsageType().equals("09") || depositBankAccInfo.getAccountUsageType().equals("07")) {
        baseAccnumFlag2 = "1";
    }
    if (DepositAccList.contains(depositBankAccInfo.getAccountUsageType() + depositBankAccInfo.getUnitPaymentAccnum())) {
        transBatchException.addBatchExceptionByErrCode("收款账号", depositBankAccInfo.getUnitPaymentAccnum(), "unitPaymentAccnum", "BPBS1011", "收款账号", depositBankAccInfo.getUnitPaymentAccnum());
    } else {
        DepositAccList.add(depositBankAccInfo.getAccountUsageType() + depositBankAccInfo.getUnitPaymentAccnum());
    }
}

改版

List<String> DepositAccList = new ArrayList<>();
String baseAccnum = "";
String baseAccnumFlag = "0";
String baseAccnumFlag2 = "0";
String linkBankNum = "";
BiPredicate<DepositBankAccInfo,String> isEquals = (d,s)->{
    return d.getAccountUsageType().equals(s);
};
TriConsumer<Boolean,Runnable,Runnable> function = (a,b,c)->{
    if(a) {
        b.run();
    }else{
        c.run();
    }
};
bankAccInfoReadList.stream().forEach(d->{
    function.accept(isEquals.test("09"),
        ()->{
                baseAccnum = d.getUnitPaymentAccnum();
        }
    )
    function.accept(isEquals.test("09")||isEquals.test("01"),
        ()->{
            baseAccnumFlag = "1";
            linkBankNum = d.getLinkBankNum();
        }
    )
    function.accept(isEquals.test("09")||isEquals.test("07"),
        ()->{
            baseAccnumFlag2 = "1";
        }
    )
    
    if (DepositAccList.contains(depositBankAccInfo.getAccountUsageType() + depositBankAccInfo.getUnitPaymentAccnum())) {
        transBatchException.addBatchExceptionByErrCode("收款账号", depositBankAccInfo.getUnitPaymentAccnum(), "unitPaymentAccnum", "BPBS1011", "收款账号", depositBankAccInfo.getUnitPaymentAccnum());
    } else {
        DepositAccList.add(depositBankAccInfo.getAccountUsageType() + depositBankAccInfo.getUnitPaymentAccnum());
    }
});

行为抽象

第一版

@Test
void t7(){
    List<String> moneys = new ArrayList<>();
    moneys.add("100");
    moneys.add("200");
    moneys.add("268");
    moneys.add("299");
    moneys.add("300");
    for (String money : moneys) {
        if(Integer.parseInt(money)>200){
            System.out.println("加钱成功: " + money);
        }else {
            System.out.println("加钱失败: " + money);
        }
    }
}

第二版

@Test
void t8(){
    TriConsumer<Boolean,Runnable,Runnable> addMoney = (a, b, c)->{
        if(a) b.run();
        else c.run();
    };

    List<String> moneys = new ArrayList<>();
    moneys.add("100");
    moneys.add("200");
    moneys.add("268");
    moneys.add("299");
    moneys.add("300");
    for (String money : moneys) {
        addMoney.accept(
            Integer.parseInt(money)>200,
            ()-> {
                System.out.println("加钱成功: " + money);
            },
            ()-> {
                System.out.println("加钱失败: " + money);
            }
        );
    }
}

第三版

@Test
void t9(){
    TriConsumer<Boolean,Runnable,Runnable> addMoney = (a, b, c)->{
        if(a) b.run();
        else c.run();
    };
    Stream.of("100","200","268","299","300")
        .forEach(m-> addMoney.accept(
            Integer.parseInt(m)>200,
            ()-> System.out.println("加钱成功: " + m),
            ()-> System.out.println("加钱失败: " + m)
        ));
}

第四版

JDK没有自带TriConsumer,是log4j提供的。故尝试另一种思路。

@Test
void t11(){
    Predicate<String> predicate = s-> Integer.parseInt(s)>200;
    BiFunction<Runnable,
    Runnable,
    Consumer<Boolean>> f = (a,b)-> c->{
        if (c) a.run(); else  b.run();
    };
    Stream.of("100","200","268","299","300")
        .forEach(m->{
            f.apply(
                ()->{
                    System.out.println("加钱成功: " + m);
                },
                ()->{
                    System.out.println("加钱失败: " + m);
                }
            ).accept(predicate.test(m));
        });
}