Java8新特性-Lambda-实战(一)

起因

今天早上和小伙伴闲聊中讲到了代码中很多switch case,或者if else if…感觉low到爆,然后大神用反射方法对这边进行了改造,代码瞬间看上去好多了。
下午review自己项目中的代码,竟然也发现了这类代码,需求是根据关键字判断关键字的类型,手机?QQ?EMAIL…,之前看了Java8实战,就有了一些想法,也对为什么要出现函数式变成,函数式接口有了一些理解,有点茅塞顿开的感觉

原始代码

首先是一个用来验证的类MatchUtil

public class MatchUtil {

/**
 * 校验是否为电话号码
 */
public static boolean isPhone(String val) {
    if (val == null || val.length() < 7) {// 至少7个字符
        return false;
    }
    Pattern pattern = Pattern
            .compile("("
                    + "^(\\+?86|\\(\\+?86\\)){0,1}\\d{11}$"
                    + "|^(\\d{3,4}|\\(\\d{3,4}\\))(-| ){0,1}(\\d{7,8})$"
                    + "|^(\\d{3,4}|\\(\\d{3,4}\\))(-| ){0,1}(\\d{7,8})(-| )(\\d{1,4})$"
                    + "|^(\\d{7,8})((-| )\\d{1,4}){0,1}$" + ")");
    return pattern.matcher(val).matches();
}


/**
 * 校验是否为QQ号码
 */
public static boolean isQQ(String val) {
    if (val == null || val.length() < 5 || val.length() > 13) {// 5-13个字符
        return false;
    }
    // 5-13位数字
    Pattern pattern = Pattern.compile("^[1-9][0-9]{4,12}$");
    return pattern.matcher(val).matches();
}

/**
 * 校验是否为Imsi号码
 */
public static boolean isImsi(String val)
{
    Pattern pattern = Pattern.compile("^460[0-9]\\d{11}$");
    return pattern.matcher(val).matches();
}

/**
 * 校验是否为合法身份证,只支持大陆身份证
 */
public static boolean isValidIDCard(String certid) {
    if (certid == null) {
        return false;
    }

    if (certid.length() == 18) {
        //此处省略方法
        return false;
    } else if (certid.length() == 15) {
        //此处省略方法
        return false;
    } else {
        return false;
    }
}

}

业务代码

由于篇幅原因,这里只列举了一部分else if 实际代码可能有10个左右吧

public class FunctionInterfacePractiseOri {

public static void main(String[] args) {

    String value = "13912911111";
    List<String> resourceTypeList = Arrays.asList("phone","qq","email","idcard","imsi");
    resourceTypeList.stream().filter(resourceType->matchResourceType(resourceType,value))
                             .findFirst().ifPresent(System.out::println);

}

/**
 * 判断关键词是否符合首页固定类型的正则
 * @param resourceType
 * @param keyword
 * @return
 */
private static boolean matchResourceType(String resourceType, String keyword){
    boolean match = true ;

    if("phone".equals(resourceType)){
        match = MatchUtil.isPhone(keyword);
    }
    else if("qq".equals(resourceType)){
        match = MatchUtil.isQQ(keyword);
    }
    else if("imsi".equals(resourceType)){
        match = MatchUtil.isImsi(keyword);
    }
    else if("idcard".equals(resourceType)){
        match = MatchUtil.isValidIDCard(keyword);
    }
    return match ;
}

}

改造开始

一开始我的思路是将类型,和正则表达式做映射,然后代码利用keyword.match(reg),这样就可以消除代码中的if else了。这条路看似不错,但是到了验证手机号码的时候,问题来了,手机号的验证不是简单的一个正则就完事了,而是通过一个方法,里面可能有复杂的业务逻辑。哎,要是可以将类型和方法做个映射关系就好了。

Wait!!!这不是需要一个函数式接口么

Lambda来发挥威力了

配合Java8提供的Lambda表达式,结合java.util.function包下面的方法,我们就可以实现方法的绑定,输入一个对象,返回boolean类型的逻辑可以使用的Predicate

public class FunctionInterfacePractise2 {

private static Map<String,Predicate<String>> typeRegMap = new HashMap<>();

static {
    //传入Lambda表达式,这里就可以传入方法了
    typeRegMap.put("phone", (keyword)->MatchUtil.isPhone(keyword));
    //优化成函数引用写法
    typeRegMap.put("qq",MatchUtil::isQQ);
    typeRegMap.put("idcard",MatchUtil::isValidIDCard);
}

public static void main(String[] args) {

    String value = "13912911111";
    List<String> resourceTypeList = Arrays.asList("phone","qq","email","idcard","imsi");
    resourceTypeList.stream().filter(resourceType->matchResourceTypeByFunction(resourceType,value))
                             .findFirst().ifPresent(System.out::println);
}

private static boolean matchResourceTypeByFunction(String resourceType, String keyword){
    Predicate<String> predicate =typeRegMap.get(resourceType);
    return predicate.test(keyword);
}

}

总结

java8的函数式的编程思想,让传递方法变为了可能,会让我们的代码更简洁更易读


版权声明:本文为wbb9019原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。