groovy/java自实现json解析器(3)JsonArray

简介: <div class="markdown_views"><h1 id="底层数据结构实现">底层数据结构实现</h1><p>jsonArray的底层数据结构有列表(list)来维护。它的定义和构造函数初始化工作如下图所示。一般创建对象时默认不传参来构造一个空的列表。</p><pre class="prettyprint"><code class="language

底层数据结构实现

jsonArray的底层数据结构有列表(list)来维护。它的定义和构造函数初始化工作如下图所示。一般创建对象时默认不传参来构造一个空的列表。

def   jsonList //底层数据存储结构
     /**
      * 构造函数,若不传参数,默认初始一个
      */
def JsonArray( jsonList = null){
    this.jsonList = jsonList == null ? [] :jsonList
}

公共调用API

下面定义了一些对外提供的API接口工具函数:

/**
     * 根据索引返回值
     * @param index
     * @return
     */
    def get(index){
        return jsonList[index];
    }
    /**
     * 往数组添加一个值
     * @param value
     * @return
     */
    def add(value){
        jsonList << value
    }
    /**
     * 根据健删除内容,返回被删除的内容(如果不存在则返回null)
     * @param key
     * @return
     */
    def romove(index){
        return jsonList.remove(index)
    }
    /**
     * 判断是否为空
     */
    def isEmpty(){
        return jsonList.isEmpty()
    }
    /**
     * 返回数组的大小
     */
    def size(){
        return jsonList.size()
    }

核心算法实现

首先,我们定义将将字符串、数组、非Map集合转化为jsonArray对象的核心方法toJsonArray,它首先对object对象的理性判断分成两类,一类是普通json格式字符串,另一类是普通的数组或非map集合数据类型(若为map类型,则直接抛出异常,因为map应有jsonObject对象进行处理。同样类似jsonObject.
1. 关于入参object是字符串类型的,我们给出了两种解法,因为实现思路和我们上一篇讲到的jsonObject类似,因此这里不再分析,也可查看下面代码注释:

    final static toJsonArray(object) {
        JsonArray jsonArray = null
        if(object.getClass() == String.class){
            /**
             * 方法一:非递归实现json字符串格式转化
             */
            //先检查是否满足json格式要求
//          if(!ValidateJson.validate(object)){//不满足要求
//              return null//返回空
//          }
//          String jsonStr = object
//          if(! jsonStr.startsWith("[") || ! jsonStr.endsWith("]")){
//              throw new IllegalArgumentException("字符串请以[]开头结尾")
//          }
//          //浅层检测双引号合法性
////            JsonTool.checkIsDoubleQuoteLegal(jsonStr)
//          def lrMArray = JsonTool.posBrackerOfString(jsonStr,"[","]")//获取json字符串中所有中括号的位置
//          def lrBArray = JsonTool.posBrackerOfString(jsonStr,"{","}")//获取json字符串中所有大括号的位置
//          println "中括号:${lrMArray}"
//          println "大括号:${lrBArray}"
//          
//          //开始根据括号来构建jsonObject
//          //主要实现原理,根据lrBArray的特定,先存放的括号必定是最里面的,但后面存放的括号不一定包括前一个括号里面的内容
//          //故这里再次模拟一个栈来一次保存每个括号转换成的jsonObject对象,然后再后续进行序号比较
//          //若后面括号的起始端序号大于前面括号的起始端信号,说明是包含关系,则在转换后面括号为对象时,通过序号相等将前面括号对象作为后面括号对象的一员,
//          //注意此时应删除已应用的对象,具体见fromJsonObjectPart函数
//          jsonArray =  JsonTool.getJsonByMergeArray(jsonStr,lrMArray, lrBArray)
            /**
             * 方法二:通过递归实现对json格式字符串的转化,同时进行了校验,算法效率较高
             */
            jsonArray = StringToJson.jsonStringToObjectOrArray(object, false)
        }else if (object instanceof Map ){
            throw new IllegalArgumentException( "放入类型为Map的实现类,请用jsonObject转化")
            return null
        }else{//普通数组或map集合类型。直接调用递归函数
            jsonArray = recusiveToJsonArray(object)
        }
        jsonArray
    }   
  1. 若object为普通数组或非map集合类型,我们会直接调用递归函数:
    /**
     * 非字符串Object递归处理部分,涵盖数组类型、集合类型或普通对象类型的处理
     * @param object
     * @return
     */
    private final static recusiveToJsonArray(object){
        def jsonList = []
        if(object.getClass().isArray() || object instanceof Collection ){
            for( i in 0..object.size() - 1){
                jsonList << JsonObject.recusiveToJsonObject(object[i])//将该对象转换为jsonObject放入
            }
        }else{//对象类型
            jsonList << JsonObject.recusiveToJsonObject(object)
        }
         new JsonArray(jsonList)
    }

它的实现思想也是很简单,如果传入object或非map集合类型,则通过递归把里面的数据提取出来。这里有待改善的地方是,如果传入的是一个对象(这个对象还可能是普通数据类型及其包装类),一样会将其解析成容量为1的jsonArray。
下面是将jsonArray转化成普通的array类型,由于原生方法的支持,我们较容易地将其完成转化。

    /**
     * 根据类名转化为list、Set或数组等类型
     * @param clazz 为 null表明是数组类型
     * @param jsonArray
     * @return 
     */
    final static toArray(Class clazz,JsonArray jsonArray){
        if(clazz == null){
                return jsonArray.getJsonList().toArray();
        }
        def instance
        try {
            instance = clazz.newInstance()
        } catch (Exception e) {
            println "不能初始化该类的实例" + e.printStackTrace()
        }
        if(instance instanceof Collection){
            return jsonArray.getJsonList()
        }else{
            throw new IllegalArgumentException("传入类型不是数组类型或集合类型")
            return null
        }
    }

toString方法重写

下面是toString方法的定义:

    /**
     * 重写tostring方法,用json格式序列化jsonArray对象
     */
    @Override
    def  String toString() {
        StringBuffer str = JsonTool.arrayToString(this, new StringBuffer());
        return str;
    }

如果细细观察过jsonArray的各个方法定义,我们会发现,JsonObject和JsonArray是“对称”。它们很多方法的定义和实现思路都是及其相似的,通过对比我们能够更好的理解类中各个方法的实现。
从groovy来实现一个json解析器,可能核心功能就是字符串和jsonObject、jsonArray之间的转化,因为groovy是一门动态语言,因此我们不好通过反射等技巧去判断对象属性的类型,进而实现有效注入。

目录
相关文章
|
3天前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
47 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
11天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
8天前
|
Java 数据库连接 Spring
反射-----浅解析(Java)
在java中,我们可以通过反射机制,知道任何一个类的成员变量(成员属性)和成员方法,也可以堆任何一个对象,调用这个对象的任何属性和方法,更进一步我们还可以修改部分信息和。
|
1月前
|
Java 编译器
Java 泛型详细解析
本文将带你详细解析 Java 泛型,了解泛型的原理、常见的使用方法以及泛型的局限性,让你对泛型有更深入的了解。
48 2
Java 泛型详细解析
|
2月前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
57 12
|
1月前
|
存储 算法 Java
Java内存管理深度解析####
本文深入探讨了Java虚拟机(JVM)中的内存分配与垃圾回收机制,揭示了其高效管理内存的奥秘。文章首先概述了JVM内存模型,随后详细阐述了堆、栈、方法区等关键区域的作用及管理策略。在垃圾回收部分,重点介绍了标记-清除、复制算法、标记-整理等多种回收算法的工作原理及其适用场景,并通过实际案例分析了不同GC策略对应用性能的影响。对于开发者而言,理解这些原理有助于编写出更加高效、稳定的Java应用程序。 ####
|
1月前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
1月前
|
Java 数据库连接 开发者
Java中的异常处理机制:深入解析与最佳实践####
本文旨在为Java开发者提供一份关于异常处理机制的全面指南,从基础概念到高级技巧,涵盖try-catch结构、自定义异常、异常链分析以及最佳实践策略。不同于传统的摘要概述,本文将以一个实际项目案例为线索,逐步揭示如何高效地管理运行时错误,提升代码的健壮性和可维护性。通过对比常见误区与优化方案,读者将获得编写更加健壮Java应用程序的实用知识。 --- ####
|
2月前
|
数据采集 存储 Web App开发
Java爬虫:深入解析商品详情的利器
在数字化时代,信息处理能力成为企业竞争的关键。本文探讨如何利用Java编写高效、准确的商品详情爬虫,涵盖爬虫技术概述、Java爬虫优势、开发步骤、法律法规遵守及数据处理分析等内容,助力电商领域市场趋势把握与决策支持。
|
2月前
|
存储 缓存 监控
Java中的线程池深度解析####
本文深入探讨了Java并发编程中的核心组件——线程池,从其基本概念、工作原理、核心参数解析到应用场景与最佳实践,全方位剖析了线程池在提升应用性能、资源管理和任务调度方面的重要作用。通过实例演示和性能对比,揭示合理配置线程池对于构建高效Java应用的关键意义。 ####

热门文章

最新文章

推荐镜像

更多