亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

Json底層一覽

Stardustsky / 3568人閱讀

摘要:在開(kāi)始了解的原理之前,首先看一段代碼,在這里以阿里的為例。翻開(kāi)的源碼可以發(fā)現(xiàn),在其節(jié)點(diǎn)類(lèi)里面,在的基礎(chǔ)上又添加了一個(gè)和指針,那么這兩個(gè)指針就是雙向鏈表的指針??偨Y(jié)其實(shí)每一個(gè)的設(shè)計(jì)都是很精妙的

在開(kāi)始了解Json的原理之前,首先看一段代碼,在這里以阿里的FastJson為例。

public class JsonRun {
    public static void main(String[] args) {
        JSONObject jsonObject =new JSONObject();
        jsonObject.put("id","a");
        jsonObject.put("name","b");
        System.out.println(jsonObject.toJSONString());
    }
}

當(dāng)看到上述代碼的時(shí)候,可能一般的程序員都會(huì)想到的是輸出為如下Json

{"id":"a","name":"b"}
但是運(yùn)行這段程序,你會(huì)發(fā)現(xiàn)控制臺(tái)打印出來(lái)的是如下代碼:
{"name":"b","id":"a"}

那么為什么會(huì)出現(xiàn)這種情況呢,翻開(kāi)FastJson的源碼便知道了,首先定位到 JsonObject 這個(gè)類(lèi)的構(gòu)造函數(shù),如下:

public JSONObject(int initialCapacity, boolean ordered){
        if (ordered) {
            map = new LinkedHashMap(initialCapacity);
        } else {
            map = new HashMap(initialCapacity);
        }
    }

這里的 ordered 為一個(gè)構(gòu)造參數(shù),表示的是是否按照順序添加,此處先不管,然后可以發(fā)現(xiàn)在阿里的FastJson中,其實(shí)默認(rèn)的Json實(shí)現(xiàn)是一個(gè)Map,那么對(duì)于LinkedHashMap來(lái)講,它是一個(gè)map和雙向鏈表的整合體,所以在LinkedList中,每一個(gè)Node都會(huì)有一個(gè)前指針和一個(gè)后指針

HashMap

LinkedHashMap 是一個(gè)HashMap的變種,大家都知道,一個(gè)HashMap是由一個(gè)桶和一個(gè)桶后面的節(jié)點(diǎn)組成的,而桶其實(shí)是一個(gè)數(shù)組,每一個(gè)桶的索引所對(duì)應(yīng)的值都是由Hash()函數(shù)計(jì)算得出的。那么這樣就會(huì)導(dǎo)致桶的元素是一個(gè)亂序的存儲(chǔ)的,例如在本段代碼中的idname,它們所在的桶索引可能是:

這樣就導(dǎo)致了一個(gè)問(wèn)題,就是Json的鍵的順序是無(wú)法保證的,那么既然HashMap是無(wú)法保證的,為什么LinkedHashMap卻可以保證順序。

LinkedHashMap

翻開(kāi)LinkedHashMap的源碼可以發(fā)現(xiàn),在其節(jié)點(diǎn)類(lèi)里面,LinkedHashMap在 HashMap的Entry基礎(chǔ)上又添加了一個(gè)beforeafter指針,

  static class Entry extends HashMap.Node {
        Entry before, after;
        Entry(int hash, K key, V value, Node next) {
            super(hash, key, value, next);
        }
    }

那么這兩個(gè)指針就是雙向鏈表的指針。有了這兩個(gè)指針之后,每一個(gè)新插入的節(jié)點(diǎn)都會(huì)知道他的前驅(qū)結(jié)點(diǎn)和后置節(jié)點(diǎn),那么對(duì)于LinkedHashMap的插入順序就會(huì)有保證了。所以其對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)如圖:

在這個(gè)結(jié)構(gòu)里面,桶索引是id的第一個(gè)節(jié)點(diǎn)是一個(gè)頭節(jié)點(diǎn),在新插入name的時(shí)候,LinkedHashMap會(huì)將head節(jié)點(diǎn)的after指針指向name,所以雖然這是一個(gè)HashMap,但是它的順序還是可以保證的。

LinkedHashMap的迭代

區(qū)別于HashMap以索引的方式進(jìn)行迭代,LinkedHashMap是以鏈表的指針進(jìn)行迭代的,如以下代碼所示:

abstract class LinkedHashIterator {
        LinkedHashMap.Entry next;
        LinkedHashMap.Entry current;
        int expectedModCount;

        LinkedHashIterator() {
            next = head;
            expectedModCount = modCount;
            current = null;
        }


final LinkedHashMap.Entry nextNode() {
            LinkedHashMap.Entry e = next;  //next就是head節(jié)點(diǎn)
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (e == null)
                throw new NoSuchElementException();
            current = e;
            next = e.after; //此處每一次的迭代都是鏈表的after
            return e;
        }

可以看到在每一次迭代的時(shí)候LinkedHashMap都是以鏈表的next節(jié)點(diǎn)作為下一個(gè)迭代,那么HashMap呢?

HashMap的迭代
abstract class HashIterator {
        Node next;        // next entry to return
        Node current;     // current entry
        int expectedModCount;  // for fast-fail
        int index;             // current slot

HashIterator() {
            expectedModCount = modCount;
            Node[] t = table;
            current = next = null;
            index = 0;
            if (t != null && size > 0) { // advance to first entry
                do {} while (index < t.length && (next = t[index++]) == null);
            }
        }


final Node nextNode() {
            Node[] t;
            Node e = next;
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (e == null)
                throw new NoSuchElementException();
            if ((next = (current = e).next) == null && (t = table) != null) {
                do {} while (index < t.length && (next = t[index++]) == null);
            }
            return e;
        }

注意這一段代碼

 if (t != null && size > 0) { // advance to first entry
        do {} while (index < t.length && (next = t[index++]) == null);
   }

這一段代碼的作用是找出table[]中第一個(gè)不為null的桶,所以其實(shí)HashMap的迭代就是依據(jù)桶中的順序來(lái)的,但是LinkedHashMap則是按找鏈表的順序來(lái)的。

總結(jié)

其實(shí)每一個(gè)java的設(shè)計(jì)都是很精妙的...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/77055.html

相關(guān)文章

  • 近幾個(gè)月Github上最熱門(mén)的Java項(xiàng)目一覽

    摘要:今天逛了逛,順手精選出了一下近幾個(gè)月以來(lái)上最熱門(mén)的個(gè)項(xiàng)目。相關(guān)閱讀正式開(kāi)源,幫助應(yīng)用快速容器化未來(lái)可能會(huì)上熱門(mén)的項(xiàng)目地址介紹哈哈,皮一下很開(kāi)心。這是我自己開(kāi)源的一份文檔,目前仍在完善中,歡迎各位英雄好漢一起完善。 showImg(https://segmentfault.com/img/remote/1460000015766827?w=391&h=220);今天逛了逛Github,順...

    cyqian 評(píng)論0 收藏0
  • UPYUN首創(chuàng)CDN實(shí)時(shí)監(jiān)控,性能狀態(tài)一覽無(wú)遺

    摘要:云加速服務(wù)商日前宣布,正式推出實(shí)時(shí)狀態(tài)與性能監(jiān)控功能。的實(shí)時(shí)狀態(tài)和性能監(jiān)控,覆蓋全國(guó)所有省份,幫助所有用戶(hù)直接全面了解服務(wù)情況,及時(shí)發(fā)現(xiàn)定位和解決突發(fā)問(wèn)題,實(shí)現(xiàn)產(chǎn)品性能的最大優(yōu)化。 云加速服務(wù)商 UPYUN 日前宣布,正式推出 CDN 實(shí)時(shí)狀態(tài)與性能監(jiān)控功能。通過(guò)對(duì)全國(guó) 120 個(gè) CDN 節(jié)點(diǎn)日志的數(shù)據(jù)分析,將速度、耗時(shí)、ISP 線(xiàn)路、地區(qū)、請(qǐng)求占比等多維度的精準(zhǔn)數(shù)據(jù),以地圖的方式具...

    lingdududu 評(píng)論0 收藏0
  • web 應(yīng)用常見(jiàn)安全漏洞一覽

    摘要:應(yīng)用常見(jiàn)安全漏洞一覽注入注入就是通過(guò)給應(yīng)用接口傳入一些特殊字符,達(dá)到欺騙服務(wù)器執(zhí)行惡意的命令。此外,適當(dāng)?shù)臋?quán)限控制不曝露必要的安全信息和日志也有助于預(yù)防注入漏洞。 web 應(yīng)用常見(jiàn)安全漏洞一覽 1. SQL 注入 SQL 注入就是通過(guò)給 web 應(yīng)用接口傳入一些特殊字符,達(dá)到欺騙服務(wù)器執(zhí)行惡意的 SQL 命令。 SQL 注入漏洞屬于后端的范疇,但前端也可做體驗(yàn)上的優(yōu)化。 原因 當(dāng)使用外...

    darkerXi 評(píng)論0 收藏0
  • web 應(yīng)用常見(jiàn)安全漏洞一覽

    摘要:應(yīng)用常見(jiàn)安全漏洞一覽注入注入就是通過(guò)給應(yīng)用接口傳入一些特殊字符,達(dá)到欺騙服務(wù)器執(zhí)行惡意的命令。此外,適當(dāng)?shù)臋?quán)限控制不曝露必要的安全信息和日志也有助于預(yù)防注入漏洞。 web 應(yīng)用常見(jiàn)安全漏洞一覽 1. SQL 注入 SQL 注入就是通過(guò)給 web 應(yīng)用接口傳入一些特殊字符,達(dá)到欺騙服務(wù)器執(zhí)行惡意的 SQL 命令。 SQL 注入漏洞屬于后端的范疇,但前端也可做體驗(yàn)上的優(yōu)化。 原因 當(dāng)使用外...

    Panda 評(píng)論0 收藏0
  • Android 研發(fā)工程師圖書(shū)一覽(2016年版)

    摘要:番茄工作法簡(jiǎn)約而不簡(jiǎn)單,本書(shū)亦然。在番茄工作法一個(gè)個(gè)短短的分鐘內(nèi),你收獲的不僅僅是效率,還會(huì)有意想不到的成就感。 @author ASCE1885的 Github 簡(jiǎn)書(shū) 微博 CSDN 知乎本文由于潛在的商業(yè)目的,不開(kāi)放全文轉(zhuǎn)載許可,謝謝! showImg(/img/remote/1460000007319503?w=728&h=792); 廣而告之時(shí)間:我的新書(shū)《Android 高...

    MadPecker 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<