起因
今天早上和小伙伴闲聊中讲到了代码中很多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版权协议,转载请附上原文出处链接和本声明。