識別Json字串並分隔成Map集合

來源:互聯網
上載者:User

標籤:

識別Json字串並分隔成Map集合前言:

最近又看了點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進行了排序,最後發現只有這個才預設沒排序:LinkedHashMap8:關於程式碼摺疊功能:

C#裡用#region和#endregion。

Java裡要下個外掛程式,然後改成//region和//endregion。

9:Java木有Internal修飾符,木有Jar包內使用的修飾符,真心不友好。10:其它的主是一些大小寫和方法的改了。

好了,先小小總結到這裡,下面上Java代碼,主要有3個類:

1:實現代碼(內部實作類別):CharState
package cyq.data.tool;/// <summary>/// 字元狀態/// </summary>class CharState{    boolean jsonStart = false;//以 "{"開始了...    boolean setDicValue = false;// 可以設定字典值了。    boolean escapeChar = false;//以"\"轉義符號開始了    /// <summary>    /// 數組開始【僅第一開頭才算】,值嵌套的以【childrenStart】來標識。    /// </summary>    boolean arrayStart = false;//以"[" 符號開始了    boolean childrenStart = false;//子級嵌套開始了。    /// <summary>    /// 【0 取名稱中】;【1 取值中】    /// </summary>    int state = -1;    /// <summary>    /// 【-1 未初始化】【0 未開始】【1 無引號開始】【2 單引號開始】【3 雙引號開始】    /// </summary>    int keyStart = -1;    /// <summary>    /// 【-1 未初始化】【0 未開始】【1 無引號開始】【2 單引號開始】【3 雙引號開始】    /// </summary>    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 && valueStart < 2 && state == 1);//未開始Json 同時 只能處理在取值之前。                break;            case ‘,‘:                isError = (!jsonStart && !arrayStart) || (jsonStart && keyStart < 2 && valueStart < 2 && state == 0);//未開始Json 同時 只能處理在取值之後。                break;            default: //值開頭。。                isError = !jsonStart || (keyStart == 0 && valueStart == 0 && state == 0);//                break;        }        //if (isError)        //{        //}    }}

 

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 < json.length(); i++)            {                c = json.charAt(i);                if (SetCharState(c, cs) && cs.childrenStart)//設定關鍵符號狀態。                {                    String item = json.substring(i);                    int[] v=GetValueLength(item, true);                    int length = v[0];                    int err=v[1];                    cs.childrenStart = false;                    if (err > 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<LinkedHashMap<String, String>> Split(String json)    {        List<LinkedHashMap<String, String>> result = new ArrayList<LinkedHashMap<String, String>>();        if (json!=null && !json.isEmpty())        {            LinkedHashMap<String, String> dic = new LinkedHashMap<String, String>();            String key = "";            StringBuilder value = new StringBuilder();            CharState cs = new CharState();            try            {                //region 核心邏輯                char c;                for (int i = 0; i < json.length(); i++)                {                    c = json.charAt(i);                    if (!SetCharState(c, cs))//設定關鍵符號狀態。                    {                        if (cs.jsonStart)//Json進行中。。。                        {                            if (cs.keyStart > 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<String, String>();                        }                    }                }                //endregion                      }            catch (Exception err)            {                Log.WriteLogToTxt(err);            }            finally            {                key = null;                value.setLength(0);                value = null;            }        }        return result;    }    /// <summary>    /// 擷取值的長度(當Json值嵌套以"{"或"["開頭時)    /// </summary>    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 < json.length(); i++)            {                c = json.charAt(i);                if (!SetCharState(c, cs))//設定關鍵符號狀態。                {                    if (!cs.jsonStart && !cs.arrayStart)//json結束,又不是數組,則退出。                    {                        break;                    }                }                else if (cs.childrenStart)//正常字元,值狀態下。                {                    int[] v=GetValueLength(json.substring(i), breakOnErr);//遞迴子值,返回一個長度。。。                    int length = v[0];                    errIndex=v[1];                    cs.childrenStart = false;                    cs.valueStart = 0;                    //cs.state = 0;                    i = i + length - 1;                }                if (breakOnErr && cs.isError)                {                    errIndex = i;                    break;                }                if (!cs.jsonStart && !cs.arrayStart)//記錄當前結束位置。                {                    len = i + 1;//長度比索引+1                    break;                }            }        }        int[] valueAndErrIndex=new int[2];        valueAndErrIndex[0]=len;        valueAndErrIndex[1]=errIndex;        return valueAndErrIndex;    }       /// <summary>    /// 設定字元狀態(返回true則為關鍵詞,返回false則當為一般字元處理)    /// </summary>    private static boolean SetCharState(char c, CharState cs)    {        switch (c)        {            case ‘{‘://[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}]                if (cs.keyStart <= 0 && cs.valueStart <= 0)                {                    cs.CheckIsError(c);                    if (cs.jsonStart && cs.state == 1)                    {                        cs.valueStart = 0;                        cs.childrenStart = true;                    }                    else                    {                        cs.state = 0;                    }                    cs.jsonStart = true;//開始。                    return true;                }                break;            case ‘}‘:                if (cs.keyStart <= 0 && cs.valueStart < 2)                {                    cs.CheckIsError(c);                    if (cs.jsonStart)                    {                        cs.jsonStart = false;//正常結束。                        cs.valueStart = 0;                        cs.setDicValue = true;                    }                    return true;                }                // cs.isError = !cs.jsonStart && cs.state == 0;                break;            case ‘[‘:                            if (!cs.jsonStart)                {                    cs.CheckIsError(c);                    cs.arrayStart = true;                    return true;                }                else if (cs.jsonStart && cs.state == 1 && cs.valueStart < 2)                {                    cs.CheckIsError(c);                    //cs.valueStart = 1;                    cs.childrenStart = true;                    return true;                }                          break;            case ‘]‘:                          if (!cs.jsonStart && cs.keyStart <= 0 && cs.valueStart <= 0)                {                    cs.CheckIsError(c);                    if (cs.arrayStart)// && !cs.childrenStart                    {                        cs.arrayStart = false;                    }                    return true;                }                        break;            case ‘"‘:            case ‘\‘‘:                cs.CheckIsError(c);                            if (cs.jsonStart)                {                    if (cs.state == 0)//key階段                    {                        cs.keyStart = (cs.keyStart <= 0 ? (c == ‘"‘ ? 3 : 2) : 0);                        return true;                    }                    else if (cs.state == 1)//值階段                    {                        if (cs.valueStart <= 0)                        {                            cs.valueStart = (c == ‘"‘ ? 3 : 2);                            return true;                        }                        else if ((cs.valueStart == 2 && c == ‘\‘‘) || (cs.valueStart == 3 && c == ‘"‘))                        {                            if (!cs.escapeChar)                            {                                cs.valueStart = 0;                                return true;                            }                            else                            {                                cs.escapeChar = false;                            }                        }                    }                }                              break;            case ‘:‘:                cs.CheckIsError(c);                         if (cs.jsonStart && cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 0)                {                    cs.keyStart = 0;                    cs.state = 1;                    return true;                }                // cs.isError = !cs.jsonStart || (cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 1);                break;            case ‘,‘:                cs.CheckIsError(c);                           if (cs.jsonStart && cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 1)                {                    cs.state = 0;                    cs.valueStart = 0;                    cs.setDicValue = true;                    return true;                }                else if (cs.arrayStart && !cs.jsonStart)                {                    return true;                }                break;            case ‘ ‘:            case ‘\r‘:            case ‘\n‘:                if (cs.jsonStart && cs.keyStart <= 0 && cs.valueStart <= 0)                {                    return true;//跳過空格。                }                break;            default: //值開頭。。                cs.CheckIsError(c);                if (c == ‘\\‘) //轉義符號                {                    if (cs.escapeChar)                    {                        cs.escapeChar = false;                    }                    else                    {                        cs.escapeChar = true;                        return true;                    }                }                else                {                    cs.escapeChar = false;                }                if (cs.jsonStart)                {                    if (cs.keyStart <= 0 && cs.state <= 0)                    {                        cs.keyStart = 1;//無引號的                    }                    else if (cs.valueStart <= 0 && cs.state == 1)                    {                        cs.valueStart = 1;//無引號的                    }                }                break;        }        return false;    }}
3:實現代碼(外部調用類):JsonHelper
package cyq.data.tool;import java.util.*;public class JsonHelper {     /// <summary>    /// 檢測是否Json格式的字串    /// </summary>    /// <param name="json">要檢測的字串</param>    public static boolean IsJson(String json)    {        return JsonSplit.IsJson(json);    }      /// <summary>    /// 將Json分隔成索引值對。    /// </summary>    public static Map<String, String> Split(String json)    {        List<LinkedHashMap<String, String>> result = JsonSplit.Split(json);        if (result != null && result.size() > 0)        {            return result.get(0);        }        return null;    }    /// <summary>    /// 將Json 數組分隔成多個索引值對。    /// </summary>    public static List<LinkedHashMap<String, String>> SplitArray(String jsonArray)    {        if (jsonArray==null || jsonArray.isEmpty())        {            return null;        }        jsonArray = jsonArray.trim();        return JsonSplit.Split(jsonArray);    }}

 

4:實現代碼(單元測試類):JsonTest

PS:標籤Key沒用引號,所以識別是false,但Split方法是相容不strict 模式的,所以還能分成Map。

總結:

總體而言,雖然Java很原始,C#很進階,但技術這東西,走向一個極端後,也得學學大閘蟹,得橫著走。

只有兩手抓,兩手都硬的時候,才不會被技術所孤立。。。

識別Json字串並分隔成Map集合

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.