前言
資料校驗是業務模組開發中必不可少的部分,資料的安全關係到系統是否正常執行,在最近的業務開發工作中,我便遇到了對配置檔案資訊進行校驗的需求。配置檔案是系統非常重要的一部分,如果配置檔案資料配置錯誤,那麼系統基本上也就完了。所以必須對資料可靠性進行校驗。
需求說明
讀取配置檔案資訊儲存到記憶體,並提供介面給其他模組呼叫。(需要對空資料,重複資料進行剔除)
實現過程
配置檔案資訊:
第一次嘗試:
剛開始寫我的想法是將語言json
資料轉換成Map
集合,然後通過fastjson
框架將資料轉換成相應的語言物件Map
集合,通過對Map
中資料遍歷進行空資料剔除和資料重複剔除操作,這種方法確實是實現了我想要的功能。
第一次嘗試思考回顧:
因為我需要讀取好幾個Json
檔案,我用上述方法實現第二個配置檔案讀取的時候,我徹底受不了了,此時我在想有什麼方法可以去重的嗎,我想到了HashMap
中key值是不允許重複的,所以我想著使用HashMap
去解決這個問題,我去網上也找了資料,確實HashMap
key不重複可以解決去重問題,但是對於我的需求還是不夠。(第一種實現程式碼就不貼出來了,實在太難看T_T)
所以此時我想到了集合框架,平時常用的集合類主要是List,HashMap
等,對其他集合類根本不熟悉。我決定對集合框架進行深入學習。果然通過對Set
的學習,我找到了解決方法,Set
集合不允許存在重複物件,我們也可以自定義重複的標準。所以我決定第二次嘗試。
第二次嘗試:使用TreeSet解決
-
TreeSet
是一個儲存不重複資料,並能對資料進行排序的集合。此處正是用來資料排序這個特點實現的。我們可以重寫物件比較的方法:compareTo()
實現控制物件是否塞進Set
集合。 -
實現程式碼:
1、定義Language
類,需要實現Comparable
介面,此介面的compareTo()
方法即為物件重複的比較方法
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Language implements Comparable<Language>{
private Integer id;
private String name;
private String abbr;
private String desc;
/**
* 實現compareTo方法,以在TreeSet中對語言物件進行去重及去空
* @param language
* @return
*/
@Override
public int compareTo(Language language) {
/*返回轉態值說明
* 返回0,說明物件不塞進TreeSet中
* 返回-1和1,物件不重複,塞進Set中,值只是關係到物件排序問題
*/
//名稱和縮寫屬性非空校驗,如果存在某個屬性為空,則返回0
if(this.getName()==null||this.getAbbr()==null||language.getAbbr()==null || language.getName()==null||
this.getName().equals("")||this.getAbbr().equals("")||language.getName().equals("")||language.getAbbr().equals("")){
return 0;
}
//名稱和縮寫屬性重複校驗,如果存在某個屬性相同則判斷為重複物件,返回0
if(this.getName().equals(language.getName())||this.getAbbr().equals(language.getAbbr())){
return 0;
}
//通過id進行順序比較,返回-1,說明id小
if (this.getId()<language.getId()) {
return -1;
}
if (this.getId()>language.getId()) {
return 1;
}
else {
//如果id相等的話就無法新增
return 0;
}
}
}
複製程式碼
2、主體實現方法:此處是監聽nacos
動態配置的json
資料,info
即為讀取到的json
資料
public void listen(String dataId,String group){
nacosListener.listenConfig(dataId,group,(String info)->{
logger.info("開始讀取語言配置");
//使用fastjson轉換json資料為Map資料
Map languages= JSONObject.parseObject(info,Map.class);
Set<Language> languageSet=new TreeSet<>();
//轉換成語言物件Set,此時將資料塞進Set中,Set會去呼叫物件compareTo()方法
languages.forEach((k,v)->{
//TreeSet中compareTo()方法進行重寫,以去除重複資料及空資料
Language language=JSONObject.parseObject(v.toString(),Language.class);
Integer id=Integer.parseInt(k.toString());
language.setId(id);
languageSet.add(language);
});
//將資料變儲存到快取中
languageSet.forEach((language)->LanguageCache.languageMap.put(language.getId().toString(),language));
logger.info("讀取語言資料完成");
});
}
複製程式碼
第二次嘗試總結:
顯然第二次方法是很簡便的,避免了對Map
集合的重複遍歷(第一次的時候我需要對Map
進行三次遍歷),提高了效能,程式碼也簡潔了;
由此我也知道了作為一個程式設計師,熟練掌握基礎知識的重要性,懂得原理,才能更好的去使用工具!!!,資料結構和演算法是我們必須熟練掌握的基礎知識。所以建議大家對基礎知識還是得掌握。