数据校验---记一次读取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进行三次遍历),提高了性能,代码也简洁了;
  由此我也知道了作为一个程序员,熟练掌握基础知识的重要性,懂得原理,才能更好的去使用工具!!!,数据结构和算法是我们必须熟练掌握的基础知识。所以建议大家对基础知识还是得掌握。

猜你喜欢

转载自juejin.im/post/5c95e5256fb9a070fe0ddd71