ITPub博客

首页 > IT职业 > IT生活 > Java版本:识别Json字符串并分隔成Map集合

Java版本:识别Json字符串并分隔成Map集合

IT生活 作者:zhuyg 时间:2021-09-09 09:43:12 0 删除 编辑

前言:

最近又看了点Java的知识,于是想着把CYQ.Data V5迁移到Java版本。

过程发现坑很多,理论上看大部分很相似,实践上代码写起来发现大部分都要重新思考方案。

遇到的C#转Java的一些小问题:

1:C#的ref:这个参数的主要意图是:

就算方法内部重新对参数重新(new)赋值,也能保证外部的参数指向新的值。

Java木有了,不知道新的方案是什么?还是说只能避免方法内部重新(new)赋值?

2:C#的out:这个参数的主要意图是:

处理多值返回的问题。

Java木有了,只能改返回数组了。

3:C#的SqlDbType和DbType

其实我也没想过C#为什么还要搞个DbType(用在DbParameter参数上使用)

Java:涉入不深,不知道用啥代替?

4:C#的DBNull.Value

Java:好像木有这东东,用啥代替?

5:C#的ChangeType 通用类型转换

Java:涉入不深,不知道用啥代替?

6:C#的反射Type有属性可以识别是否泛型(IsGenericType)和Nullable.GetUnderlyingType(t)

Java:在Class里找不到泛型判断,替代方案是?

7:发现Map集合的大多数默认都对key进行了排序,最后发现只有这个才默认没排序:LinkedHashMap

8:关于代码折叠:

C#里用#region和#endregion。

Java里要下个插件,然后改成//region和//endregion。

9:Java木有Internal修饰符,木有Jar包内使用的修饰符,真心不友好。

10:其它的主是一些大小写和方法的改了。

好了,先小小总结到这里,下面上Java代码,主要有3个类:

图片描述

1:实现代码(内部实现类):CharState

图片描述

package cyq.data.tool;/// /// 字符状态/// class CharState{    boolean jsonStart = false;//以 "{"开始了...    boolean setDicValue = false;// 可以设置字典值了。    boolean escapeChar = false;//以""转义符号开始了    ///     /// 数组开始【仅第一开头才算】,值嵌套的以【childrenStart】来标识。    ///     boolean arrayStart = false;//以"[" 符号开始了    boolean childrenStart = false;//子级嵌套开始了。    ///     /// 【0 取名称中】;【1 取值中】    ///     int state = -1;    ///     /// 【-1 未初始化】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】    ///     int keyStart = -1;    ///     /// 【-1 未初始化】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】    ///     int valueStart = -1;    boolean isError = false;//是否语法错误。    void CheckIsError(char c)//只当成一级处理(因为GetLength会递归到每一个子项处理)    {        switch (c)        {            case '{'://[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}]                isError = jsonStart && state == 0;//重复开始错误 同时不是值处理。                break;            case '}':                isError = !jsonStart || (keyStart > -1 && state == 0);//重复结束错误 或者 提前结束。                break;            case '[':                isError = arrayStart && state == 0;//重复开始错误                break;            case ']':                isError = !arrayStart;//重复开始错误                break;            case '"':            case ''':                isError = !jsonStart;//未开始Json                break;            case ':':                isError = !jsonStart || (jsonStart && keyStart 

图片描述

 

2:实现代码(内部实现类):JsonSplit

PS:Log这个类的代码可以先注释屏蔽。

图片描述

package cyq.data.tool;import java.util.*;import cyq.data.Log;public class JsonSplit{    public static boolean IsJson(String json)    {        return IsJsonAndBackIndex(json)==-1;    }    public static int IsJsonAndBackIndex(String json)    {        if(json==null || json.isEmpty() || json.length()==1)        {            return 0;                    }                if ((json.charAt(0) == '{' && json.charAt(json.length() - 1) == '}') ||            (json.charAt(0)== '[' && json.charAt(json.length() - 1)== ']'))        {            int errIndex = 0;            CharState cs = new CharState();            char c;            for (int i = 0; i  0)                    {                        errIndex = i + err;                        return errIndex;                    }                    i = i + length - 1;                }                if (cs.isError)                {                    errIndex = i;                    return errIndex;                }            }            if( !cs.arrayStart && !cs.jsonStart)            {                return -1;            }            return errIndex;        }        else        {            return 0;        }    }    static List> Split(String json)    {        List> result = new ArrayList>();        if (json!=null && !json.isEmpty())        {            LinkedHashMap dic = new LinkedHashMap();            String key = "";            StringBuilder value = new StringBuilder();            CharState cs = new CharState();            try            {                //region 核心逻辑                char c;                for (int i = 0; i  0)                            {                                key += c;                            }                            else if (cs.valueStart > 0)                            {                                value.append(c);                                //value += c;                            }                        }                        else if (!cs.arrayStart)//json结束,又不是数组,则退出。                        {                            break;                        }                    }                    else if (cs.childrenStart)//正常字符,值状态下。                    {                        String item = json.substring(i);                        int[] v= GetValueLength(item, false);                        int length =v[0];                        //int temp=v[1];                        //value = item.SubString(0, length);                        value.setLength(0);                        value.append(item.substring(0, length));                        cs.childrenStart = false;                        cs.valueStart = 0;                        //cs.state = 0;                        cs.setDicValue = true;                        i = i + length - 1;                    }                    if (cs.setDicValue)//设置键值对。                    {                        if (key!=null && !key.isEmpty() && !dic.containsKey(key))                        {                            //if (value != String.Empty)                            //{                            boolean isNull = json.charAt(i - 5) == ':' && json.charAt(i) != '"' && value.length() == 4 && value.toString() == "null";                            if (isNull)                            {                                value.setLength(0);                            }                            dic.put(key, value.toString());                            //}                        }                        cs.setDicValue = false;                        key = "";                        value.setLength(0);                    }                    if (!cs.jsonStart && dic.size() > 0)                    {                        result.add(dic);                        if (cs.arrayStart)//处理数组。                        {                            dic = new LinkedHashMap();                        }                    }                }                //endregion                      }            catch (Exception err)            {                Log.WriteLogToTxt(err);            }            finally            {                key = null;                value.setLength(0);                value = null;            }        }        return result;    }    ///     /// 获取值的长度(当Json值嵌套以"{"或"["开头时)    ///     private static int[] GetValueLength(String json, boolean breakOnErr)    {                int errIndex = 0;        int len = 0;        if (json!=null && !json.isEmpty())        {            CharState cs = new CharState();            char c;            for (int i = 0; i     /// 设置字符状态(返回true则为关键词,返回false则当为普通字符处理)    ///     private static boolean SetCharState(char c, CharState cs)    {        switch (c)        {            case '{'://[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}]                if (cs.keyStart 

图片描述

3:实现代码(外部调用类):JsonHelper

图片描述

package cyq.data.tool;import java.util.*;public class JsonHelper {     ///     /// 检测是否Json格式的字符串    ///     /// 要检测的字符串    public static boolean IsJson(String json)    {        return JsonSplit.IsJson(json);    }      ///     /// 将Json分隔成键值对。    ///     public static Map Split(String json)    {        List> result = JsonSplit.Split(json);        if (result != null && result.size() > 0)        {            return result.get(0);        }        return null;    }    ///     /// 将Json 数组分隔成多个键值对。    ///     public static List> SplitArray(String jsonArray)    {        if (jsonArray==null || jsonArray.isEmpty())        {            return null;        }        jsonArray = jsonArray.trim();        return JsonSplit.Split(jsonArray);    }}

图片描述

 

4:实现代码(单元测试类):JsonTest

图片描述

PS:标签Key没用引号,所以识别是false,但Split方法是兼容不严格模式的,所以还能分成Map。

总结:

总体而言,虽然Java很原始,C#很高级,但技术这东西,走向一个极端后,也得学学大闸蟹,得横着走。

只有两手抓,两手都硬的时候,才不会被技术所孤立。。。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/861/viewspace-2806513/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-04-12

  • 博文量
    115
  • 访问量
    1101