基礎提高(二):分析IntHashMap

一概荷、IntHashMap

1.1 準備

  • 先從官網下載jar包:javasoft-collection.jar式曲,解壓后將jar包build到Java項目中.

1.2 IntHashMap類圖

1

1.3 IntHashMap流程圖

2

從上面類圖可以看出IntHashMap和HashMap一樣都是基于Map接口而涉,在Map中最常用的2個方法是put()和get()方法削葱。大家都知道Map是從鍵到值的映射惫撰,每個鍵不能出現(xiàn)重復且每個鍵最多只能映射到一個值瞭空。那么IntHashMap是如何保證鍵的唯一性杆兵?可能大家會想IntHashMap的鍵是int類型雁仲,使用==來比較,這樣子雖然能保證鍵的唯一琐脏。但是隨著元素的增加攒砖,每次都進行比較效率會越來越低。什么樣的數(shù)據結構能快速的存儲元素日裙?答案是數(shù)組吹艇。在HashMap中是通過hash計算出bucketIndex位置找到數(shù)組中對應的元素,那么IntHashMap呢昂拂?IntHashMap亦如此受神,唯一不同的是計算bucketIndex的算法。通過indexFor()方法拿到bucketindex后格侯。它會先去數(shù)組中找這個位置上的元素IntEntry<V>是否存在鼻听,如果存在的話财著,再通過key去查找value,然后將新值替換掉舊value。

代碼清單2如下:

/** 
  * Returns index for key 
  */  
protected int indexFor(int key, int length) {  
    key += ~(key << 9);  
    key ^=  (key >>> 14);  
    key +=  (key << 4);  
    key ^=  (key >>> 10);  
    return key & (length-1);  
}  

代碼清單2如下:

int i = indexFor(key, table.length);  
  
for (IntEntry<V> e = table[i]; e != null; e = e.next) {  
       if (e.key == key) {  
             V oldValue = e.value;  
             e.value = value;  
             e.recordAccess(this);  
             return oldValue;  
        }  
}  

二撑碴、IntHashMap與HashMap比較

2.1 運行效率比較

創(chuàng)建一個測試類撑教,分別往IntHashMap和HashMap各插入1萬和5萬條數(shù)據來測試它們性能、GC和內存使用

代碼如下:

package com.lll.operator;  
  
import java.util.HashMap;  
import java.util.Map;  
  
import ch.javasoft.util.intcoll.IntHashMap;  
  
public class ShiftTest {  
  
    //  IntHashMap<String> map = new IntHashMap<String>();  
    HashMap<Integer,String> map = new HashMap<Integer,String>();  
  
    public void add()  
    {  
        for (int i = 0; i < 10000;i++) {  
            for(int j = 0;j<50000;j++)  
            {  
                if(map.get(j) == null)  
                {  
                    map.put(j, "小毛驢");  
                }  
            }  
        }  
    }  
    public static void main(String[] args) {  
        long curTime = System.currentTimeMillis();  
        ShiftTest shiftTest = new ShiftTest();  
        shiftTest.add();  
        long curTime2 = System.currentTimeMillis();  
        System.out.println("耗時:"+(curTime2-curTime)+"ms");  
        try {  
            Thread.sleep(5000);  
        } catch (InterruptedException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
  
}  

2.2 Visual GC比較

HashMap:

3

IntHashMap:

4

2.3 結果分析

10000條數(shù)據測試結果:

IntHashMap

第一次取樣:795ms

第二次取樣:815ms

第三次取樣:807ms

GC時間:NO GC

HashMap

第一次取樣:866ms

第二次取樣:927ms

第三次取樣:861ms

GC時間:11.978ms

50000條數(shù)據測試結果:

IntHashMap

第一次取樣:5166ms

第二次取樣:4817ms

第三次取樣:4997ms

GC時間:NO GC

HashMap

第一次取樣:4388ms

第二次取樣:4430ms

第三次取樣:3876ms

GC時間:40.453ms

從上面的測試結果可以看出灰羽,HashMap會隨著容器大小的變化效率明顯變慢驮履。也許從數(shù)據測試結果來看使用IntHashMap在性能上比HashMap并沒有太大優(yōu)勢甚至效率還要低些,但是從GC上來看明顯IntHashMap更有優(yōu)勢廉嚼。那么是什么讓他們產生這樣的差異玫镐?

2.4 差異一

HashMap在插入元素過程中會在堆中產生大量的Integer實例(如下圖-Profiler界面),參考代碼清單4怠噪。而IntHashMap不一樣恐似,它是以int作為key值類型(見代碼清單5),能夠減少Integer實例的產生傍念,減少GC負擔矫夷。

Profiler界面

5

代碼清單4:

static class Entry<K,V> implements Map.Entry<K,V> {  
       final K key;  
       V value;  
       Entry<K,V> next;  
       int hash;  
  
       /** 
        * Creates new entry. 
        */  
       Entry(int h, K k, V v, Entry<K,V> n) {  
           value = v;  
           next = n;  
           key = k;  
           hash = h;  
        }
}

代碼清單5:

public static class IntEntry<VV> implements IntMap.IntEntry<VV> {  
    protected final int key;  
    protected VV value;  
    protected IntEntry<VV> next;  
  
    /** 
     * Create new entry. 
     */  
    protected IntEntry(int k, VV v, IntEntry<VV> n) {  
        value = v;  
        next = n;  
        key = k;  
    }
}

2.5 差異二

在遍歷時,IntHashMap(代碼清單6)沒有對hash進行比較憋槐。

代碼清單6

public V get(int key) {  
    int i = indexFor(key, table.length);  
    IntEntry<V> e = table[i];   
    while (true) {  
        if (e == null)  
            return null;  
        if (e.key == key)   
            return e.value;  
        e = e.next;  
    }  
}

HashMap遍歷代碼清單7:

final Entry<K,V> getEntry(Object key) {  
    int hash = (key == null) ? 0 : hash(key);  
    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 != null && key.equals(k))))  
            return e;  
    }  
    return null;  
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末双藕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子阳仔,更是在濱河造成了極大的恐慌忧陪,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件近范,死亡現(xiàn)場離奇詭異嘶摊,居然都是意外死亡,警方通過查閱死者的電腦和手機评矩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門叶堆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人斥杜,你說我怎么就攤上這事虱颗。” “怎么了蔗喂?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵上枕,是天一觀的道長。 經常有香客問我弱恒,道長,這世上最難降的妖魔是什么棋恼? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任返弹,我火速辦了婚禮锈玉,結果婚禮上,老公的妹妹穿的比我還像新娘义起。我一直安慰自己拉背,他們只是感情好,可當我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布默终。 她就那樣靜靜地躺著椅棺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪齐蔽。 梳的紋絲不亂的頭發(fā)上两疚,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天,我揣著相機與錄音含滴,去河邊找鬼诱渤。 笑死,一個胖子當著我的面吹牛谈况,可吹牛的內容都是我干的勺美。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼碑韵,長吁一口氣:“原來是場噩夢啊……” “哼赡茸!你這毒婦竟也來了?” 一聲冷哼從身側響起祝闻,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤占卧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后治筒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屉栓,經...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年耸袜,在試婚紗的時候發(fā)現(xiàn)自己被綠了友多。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡堤框,死狀恐怖域滥,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情蜈抓,我是刑警寧澤启绰,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站沟使,受9級特大地震影響委可,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一着倾、第九天 我趴在偏房一處隱蔽的房頂上張望拾酝。 院中可真熱鬧,春花似錦卡者、人聲如沸蒿囤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽材诽。三九已至,卻和暖如春恒傻,著一層夾襖步出監(jiān)牢的瞬間脸侥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工碌冶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留湿痢,地道東北人。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓扑庞,卻偏偏與公主長得像譬重,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子罐氨,可洞房花燭夜當晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,152評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理臀规,服務發(fā)現(xiàn),斷路器栅隐,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 在教室里走來走去塔嬉,心中也思來想去,什么都不深刻租悄,胡亂的想起谨究。 隨便開始隨便下筆的能力似乎減弱了,總是舉著手指不能落...
    俏村姑閱讀 299評論 0 0
  • matheecs閱讀 274評論 0 0
  • 身邊總有一些人鼓吹“讀書無用論”,他們常說的是讀書能提升KPI嗎潭辈?讀書能帶來更高的效益嗎鸯屿?讀書多的一定比讀書少的賺...
    趙石頭記閱讀 989評論 4 3