資料校驗---記一次讀取json配置資料,資料去重,去空

♂???木發表於2019-03-25

前言


資料校驗是業務模組開發中必不可少的部分,資料的安全關係到系統是否正常執行,在最近的業務開發工作中,我便遇到了對配置檔案資訊進行校驗的需求。配置檔案是系統非常重要的一部分,如果配置檔案資料配置錯誤,那麼系統基本上也就完了。所以必須對資料可靠性進行校驗。

需求說明


讀取配置檔案資訊儲存到記憶體,並提供介面給其他模組呼叫。(需要對空資料,重複資料進行剔除)

實現過程


配置檔案資訊:

資料校驗---記一次讀取json配置資料,資料去重,去空

第一次嘗試:


  剛開始寫我的想法是將語言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進行三次遍歷),提高了效能,程式碼也簡潔了;
  由此我也知道了作為一個程式設計師,熟練掌握基礎知識的重要性,懂得原理,才能更好的去使用工具!!!,資料結構和演算法是我們必須熟練掌握的基礎知識。所以建議大家對基礎知識還是得掌握。

相關文章