導航:首頁 > 編程語言 > json解析long格式數據類型

json解析long格式數據類型

發布時間:2025-02-12 14:57:02

json數據可以為什麼類型

從結構上看,所有來的數據(自data)最終都可以分解成三種類型:
第一種類型是標量(scalar),也就是一個單獨的字元串(string)或數字(numbers),比如"北京"這個單獨的詞。
第二種類型是序列(sequence),也就是若干個相關的數據按照一定順序並列在一起,又叫做數組(array)或列表(List),比如"北京,上海"。
第三種類型是映射(mapping),也就是一個名/值對(Name/value),即數據有一個名稱,還有一個與之相對應的值,這又稱作散列(hash)或字典(dictionary),比如"首都:北京"。
Json的規格非常簡單,只用一個頁面幾百個字就能說清楚,而且Douglas Crockford聲稱這個規格永遠不必升級,因為該規定的都規定了。
1) 並列的數據之間用逗號(", ")分隔。
2) 映射用冒號(": ")表示。
3) 並列數據的集合(數組)用方括弧("[]")表示。
4) 映射的集合(對象)用大括弧("{}")表示。

② 如何編寫一個JSON解析器

編寫一個JSON解析器實際上就是一個函數,它的輸入是一個表示JSON的字元串,輸出是結構化的對應到語言本身的數據結構。

和XML相比,JSON本身結構非常簡單,並且僅有幾種數據類型,以Java為例,對應的數據結構是:

"string":Java的String;
number:Java的Long或Double;
true/false:Java的Boolean;
null:Java的null;
[array]:Java的List<Object>或Object[];
{"key":"value"}:Java的Map<String, Object>。

解析JSON和解析XML類似,最終都是解析為內存的一個對象。出於效率考慮,使用流的方式幾乎是唯一選擇,也就是解析器只從頭掃描一遍JSON字元串,就完整地解析出對應的數據結構。

本質上解析器就是一個狀態機,只要按照JSON定義的格式(參考http://www.json.org,正確實現狀態轉移即可。但是為了簡化代碼,我們也沒必要完整地實現一個字元一個字元的狀態轉移。

解析器的輸入應該是一個字元流,所以,第一步是獲得Reader,以便能不斷地讀入下一個字元。

在解析的過程中,我們經常要根據下一個字元來決定狀態跳轉,此時又涉及到回退的問題,就是某些時候不能用next()取下一個字元,而是用peek()取下一個字元,但字元流的指針不移動。所以,Reader介面不能滿足這個需求,應當進一步封裝一個CharReader,它可以實現:

char next():讀取下一個字元,移動Reader指針;
char peek():讀取下一個字元,不移動Reader指針;
String next(int size):讀取指定的N個字元並移動指針;
boolean hasMore():判斷流是否結束。

JSON解析比其他文本解析要簡單的地方在於,任何JSON數據類型,只需要根據下一個字元即可確定,仔細總結可以發現,如果peek()返回的字元是某個字元,就可以期望讀取的數據類型:

{:期待一個JSON object;
::期待一個JSON object的value;
,:期待一個JSON object的下一組key-value,或者一個JSON array的下一個元素;
[:期待一個JSON array;
t:期待一個true;
f:期待一個false;
n:期待一個null;
":期待一個string;
0~9:期待一個number。

但是單個字元要匹配的狀態太多了,需要進一步把字元流變為Token,可以總結出如下幾種Token:

END_DOCUMENT:JSON文檔結束;
BEGIN_OBJECT:開始一個JSON object;
END_OBJECT:結束一個JSON object;
BEGIN_ARRAY:開始一個JSON array;
END_ARRAY:結束一個JSON array;
SEP_COLON:讀取一個冒號;
SEP_COMMA:讀取一個逗號;
STRING:一個String;
BOOLEAN:一個true或false;
NUMBER:一個number;
NULL:一個null。

然後,將CharReader進一步封裝為TokenReader,提供以下介面:

Token readNextToken():讀取下一個Token;
boolean readBoolean():讀取一個boolean;
Number readNumber():讀取一個number;
String readString():讀取一個string;
void readNull():讀取一個null。

由於JSON的Object和Array可以嵌套,在讀取過程中,使用一個棧來存儲Object和Array是必須的。每當我們讀到一個BEGIN_OBJECT時,就創建一個Map並壓棧;每當讀到一個BEGIN_ARRAY時,就創建一個List並壓棧;每當讀到一個END_OBJECT和END_ARRAY時,就彈出棧頂元素,並根據新的棧頂元素判斷是否壓棧。此外,讀到Object的Key也必須壓棧,讀到後面的Value後將Key-Value壓入棧頂的Map。

如果讀到END_DOCUMENT時,棧恰好只剩下一個元素,則讀取正確,將該元素返回,讀取結束。如果棧剩下不止一個元素,則JSON文檔格式不正確。

最後,JsonReader的核心解析代碼parse()就是負責從TokenReader中不斷讀取Token,根據當前狀態操作,然後設定下一個Token期望的狀態,如果與期望狀態不符,則JSON的格式無效。起始狀態被設定為STATUS_EXPECT_SINGLE_VALUE | STATUS_EXPECT_BEGIN_OBJECT | STATUS_EXPECT_BEGIN_ARRAY,即期望讀取到單個value、{或[。循環的退出點是讀取到END_DOCUMENT時。

③ 問題復盤|在使用 gson 時,數字被自動轉為 double 類型

在使用Gson進行數據轉換時,遇到數字自動轉為double類型的問題。將一個JsonObject轉換為Map後,數字全部變為double形式,年齡2變為2.0,身高98.2正常顯示,但登記時間顯示為1.694533284627E12。面對此問題,我首先嘗試通過搜索引擎尋找解決方案。發現Gson默認將number類型數據解析為double類型,並指出此問題在版本2.8.9中已修復。我查看自己使用的Gson版本為2.8.6,低於2.8.9,且存在相同問題。問題定位後,解決方法較為直接:升級Gson版本至2.8.9,並在創建Gson對象時手動設置數字類型轉換策略。完成這些步驟後,問題得到解決。總結,此問題並非首次出現,也難以避免再次發生,簡單記錄,等待有緣人參考。

閱讀全文

與json解析long格式數據類型相關的資料

熱點內容
iphone4s百度輸入法 瀏覽:192
一級文件夾 瀏覽:832
iphone九宮格輸入法調不出 瀏覽:626
win10閱讀器pdf打不開 瀏覽:22
三年級下冊數據統計你有哪些建議 瀏覽:375
可視化中文編程哪個軟體好 瀏覽:163
wordpress標簽熱門 瀏覽:641
什麼是醫學常規數據 瀏覽:367
win10下載的主題圖片在哪裡 瀏覽:918
中控考勤機通用密碼 瀏覽:774
俠客win10安裝不了驅動 瀏覽:662
桌面文件里的excel表格打不開 瀏覽:305
如何拒絕編程老師 瀏覽:24
linux查看文件後綴 瀏覽:608
u盤變小了文件也沒了 瀏覽:433
技能證在什麼網站查詢 瀏覽:945
數控編程代碼q是什麼意思 瀏覽:17
小米2s什麼版本才有專家模式 瀏覽:227
生成的html一般在哪個文件夾 瀏覽:177
word新建文檔有頁眉 瀏覽:802

友情鏈接