<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    青菜貓(孫宇博客),青菜貓(孫宇博客),青菜貓(孫宇博客)http://www.javasdc.cn/
    posts - 29,  comments - 63,  trackbacks - 0

    HashMap 是通過key_value當成一個整體進行處理,通過key的hashCoder反回一個int數,然后還會調用一個hash方法。來確定存儲位置。
    HashMap 存儲java對像,其實并沒有真正將 Java 對象放入 Set 集合中,而是多個引用變量所組成的集合,這些引用變量指向實際的 Java 對象。
    HashMap 存儲.以如下代碼為例:
    HashMap<String,String> ma = new HashMap<String,String>();
            ma.put("a", "aaa");
            ma.put("b", "bbb");
    HashMap 采用一種所謂的“Hash 算法”來決定每個元素的存儲位置。
    在上面代碼中系統會調用a的hashCode方法來確定來決定該元素的存儲位置。以下是部分源碼
    public V put(K key, V value) {
            if (key == null)
                return putForNullKey(value);
            int hash = hash(key.hashCode());
            int i = indexFor(hash, table.length);
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                    V oldValue = e.value;
                    e.value = value;
                    e.recordAccess(this);
                    return oldValue;
                }
            }

            modCount++;
            addEntry(hash, key, value, i);
            return null;
     }

    hash方法對應在下面
     static int hash(int h) {
            // This function ensures that hashCodes that differ only by
            // constant multiples at each bit position have a bounded
            // number of collisions (approximately 8 at default load factor).
            h ^= (h >>> 20) ^ (h >>> 12);
            return h ^ (h >>> 7) ^ (h >>> 4);
     }
    大家可以看下上面的Entry,我理解成其實就是一個key_value對。然后通過hash(key.hashCode())這樣確定位置。系統這樣才能存儲在那里。
    關鍵是int i = indexFor(hash, table.length);我理解是這個對找到相對應的索引塊。加快速度。包括get的時候也會調用這個方法,確實索引塊的位置.
    來看看具體算法
     static int indexFor(int h, int length) {
            return h & (length-1);
     }
    h是hash的一個值,length中這個table的長度。假設 h=5,length=16, 那么 h & length - 1 將得到 5,這個length為什么我會假設是16,大家可以看看源碼
    也就知道static final int DEFAULT_INITIAL_CAPACITY = 16; 初始化的時候就是16。這樣目的在于計算得到的索引值總是位于 table 數組的索引之內
    根據上面 put 方法的源代碼可以看出,當程序試圖將一個 key-value 對放入 HashMap 中時,
    程序首先根據該 key 的 hashCode() 返回值決定該 Entry 的存儲位置:如果兩個 Entry 的 key 的 hashCode() 返回值相同,
    那它們的存儲位置相同。如果這兩個 Entry 的 key 通過 equals 比較返回 true,
    新添加 Entry 的 value 將覆蓋集合中原有 Entry 的 value,但 key 不會覆蓋。如果這兩個 Entry 的 key 通過 equals 比較返回 false
    ,新添加的 Entry 將與集合中原有 Entry 形成 Entry 鏈,而且新添加的 Entry 位于 Entry 鏈的頭部——具體說明繼續看 addEntry() 方法的說明。

    void addEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K,V> e = table[bucketIndex];
            table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
            if (size++ >= threshold)
                resize(2 * table.length);
        }
    大家看看這里就知道了, 就是把添加的 Entry 對象放入 table 數組的 bucketIndex 索引處——如果 bucketIndex 索引處已經有了一個 Entry 對象,那新添加的 Entry 對象指向原有的 Entry 對象(產生一個 Entry 鏈),
    如果 bucketIndex 索引處沒有 Entry 對象,也會新放入的 Entry 對象指向 null,也就是沒有產生 Entry 鏈。
     如果 Map 中的 key-value 對的數量超過了極限,就會度擴充到 2 倍。
    HashMap的取值
    public V get(Object key) {
            if (key == null)
                return getForNullKey();
            int hash = hash(key.hashCode());
            for (Entry<K,V> e = table[indexFor(hash, table.length)];
                 e != null;
                 e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                    return e.value;
            }
            return null;
        }
    其實也是先要找到對應的位置,HashMap是用equals判斷當前鍵是否和表中的鍵相同。所以在這里要說明如果要用自己的類做為HashMap的鍵,必須同時重載wqual()和hashCode()









    posted on 2010-09-01 11:39 青菜貓(孫宇) 閱讀(2236) 評論(1)  編輯  收藏 所屬分類: java


    FeedBack:
    # re: HashMap源碼解析
    2010-09-02 09:44 | 瀧洲彼岸-Scelong
    所以在這里要說明如果要用自己的類做為HashMap的鍵,必須同時重載wqual()和hashCode()

    樓主,這里的“重載”是不是應該為重寫或覆蓋呢?  回復  更多評論
      
    <2010年9月>
    2930311234
    567891011
    12131415161718
    19202122232425
    262728293012
    3456789

    青菜貓(孫宇)結交天下朋友,在網上吸取知識..

    常用鏈接

    留言簿(16)

    隨筆分類

    隨筆檔案

    文章分類

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    青菜貓(孫宇博客),青菜貓(孫宇博客),青菜貓(孫宇博客)http://www.javasdc.cn/
    主站蜘蛛池模板: 亚洲国产高清精品线久久| 亚洲色丰满少妇高潮18p| 在线看免费观看AV深夜影院| 亚洲中文字幕一区精品自拍| 亚洲国产成人久久综合一区77| 国内精品免费在线观看| 亚洲卡一卡二卡乱码新区| 91免费福利视频| 亚洲一本之道高清乱码| 亚洲高清免费视频| 亚洲无砖砖区免费| 一级毛片在线免费播放| 亚洲精品一卡2卡3卡三卡四卡| 亚洲一区二区三区国产精华液| 羞羞视频免费网站在线看| 成人午夜大片免费7777| 亚洲理论片在线中文字幕| 免费国内精品久久久久影院| 久久久久久国产精品免费免费男同| 亚洲人成网站免费播放| 亚洲AV无码国产在丝袜线观看| 国产精品jizz在线观看免费| 亚洲国产精品无码观看久久| 亚洲AV天天做在线观看| 一本色道久久88亚洲综合| 一区二区三区在线免费观看视频 | www成人免费视频| 亚洲精品国产精品国自产网站 | 亚洲第一香蕉视频| 亚洲一区二区三区无码影院| 日韩一区二区a片免费观看| 精品一卡2卡三卡4卡免费视频| 国产精品亚洲一区二区三区久久 | 成在线人直播免费视频| 精品亚洲成a人片在线观看| 亚洲日本韩国在线| 精品国产一区二区三区免费看 | 中文字幕亚洲一区二区三区| 二级毛片免费观看全程| 久久夜色精品国产噜噜亚洲a| 亚洲成人免费在线|