Java8新特性-Lambda-實戰(一)
阿新 • • 發佈:2019-01-25
起因
今天早上和小夥伴閒聊中講到了程式碼中很多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了。這條路看似不錯,但是到了驗證手機號碼的時候,問題來了,手機號的驗證不是簡單的一個正則就完事了,而是通過一個方法,裡面可能有複雜的業務邏輯。哎,要是可以將型別和方法做個對映關係就好了。
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);
}
}