數(shù)據(jù)結(jié)構(gòu)篇 09最欠、哈希表 -- 簡化版 HashMap,一線互聯(lián)網(wǎng)移動架構(gòu)師 360°全方面性能調(diào)優(yōu)

12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741}; java交流737251827

privatestaticfinalintupperTol=10;

privatestaticfinalintlowerTol=2;

privateintcapacityIndex=0;

privateTreeMap[] hashtable;

privateintsize;

privateintM;

//java學(xué)習(xí)交流:737251827

publicHashTable(){this.M = capacity[capacityIndex];

size =0;hashtable =newTreeMap[M];

for(inti=0; i < M ; i ++)

hashtable[i] =newTreeMap<>();

? ? }

privateinthash(K key){

return(key.hashCode() &0x7fffffff) % M;

? ? }

publicintgetSize(){

returnsize;

? ? }

}

2惩猫、往哈希表中添加元素

通過 hash 函數(shù)計算元素的數(shù)組索引芝硬,通過此索引在 hashtable 數(shù)組中找到 TreeMap,如果此 key 已存在 map 中轧房,那么直接覆蓋拌阴,如果不存在,直接添加到 map 中奶镶;而此 map 的底層實(shí)現(xiàn)是紅黑樹迟赃,所以我們的哈希表的底層實(shí)現(xiàn)可以認(rèn)為是數(shù)組加紅黑樹的實(shí)現(xiàn);

添加完元素檢查是否需要擴(kuò)容厂镇,擴(kuò)容思想就是自增 capacityIndex 索引纤壁,然后去 capacity 數(shù)組中找對應(yīng)的素數(shù)即可,這樣保證了每次擴(kuò)容后容量都是一個對應(yīng)哈希表數(shù)據(jù)規(guī)模的素數(shù)捺信;

resize 函數(shù)也非常簡單酌媒,新建一個 TreeMap 數(shù)組,將原 map 數(shù)組中所有值復(fù)制到新數(shù)組迄靠,復(fù)制的過程有幾個需要注意的點(diǎn)秒咨,先保存一下原數(shù)組的大小,再將 M 賦值為新數(shù)組的大小掌挚,為什么需要這么做雨席?因?yàn)榈谝粚?for 循環(huán)需要遍歷的是原數(shù)組的大小,而第二層 foreach 循環(huán)求元素在新數(shù)組的 hash 值時需要使用新數(shù)組的大蟹褪健舅世;最后將 hashtable 引用指向新的數(shù)組;

publicvoidadd(K key, V value){

? ? TreeMap<K, V> map = hashtable[hash(key)];

if(map.containsKey(key))

? ? ? ? ? ? map.put(key, value);

else{

? ? ? ? ? ? map.put(key, value);size ++;

if(size >= upperTol * M && capacityIndex +1< capacity.length){

? ? ? ? ? ? capacityIndex ++;? ?

? ? ? ? ? ? resize(capacity[capacityIndex]);

? ? ? ? }

? ? }

}

privatevoidresize(intnewM){

TreeMap[]newHashTable=newTreeMap[newM];

for(inti=0; i < newM ; i ++)

newHashTable[i] =newTreeMap<>();

intoldM=M;

this.M = newM;

for(inti=0; i < oldM ; i ++){

? ? ? ? ? ? TreeMap<K, V> map = hashtable[i];

for(K key: map.keySet())

? ? ? ? ? ? newHashTable[hash(key)].put(key, map.get(key));

}

this.hashtable = newHashTable;

}

3奇徒、從哈希表中移除元素

首先通過 hash 函數(shù)計算元素在數(shù)組中的索引,然后通過此索引去 hashtable 數(shù)組中找對應(yīng) map缨硝,如果 map 包含此元素摩钙,直接從 map 中刪除元素即可;最后檢查一下是否需要縮容查辩,原理跟擴(kuò)容是完全相同的胖笛;

publicVremove(K key){

Vret=null;

? ? ? TreeMap<K, V> map = hashtable[hash(key)];

if(map.containsKey(key)){

? ? ? ? ret = map.remove(key);

? ? ? ? size --;

if(size < lowerTol * M && capacityIndex -1>=0){

? ? ? ? capacityIndex --;

? ? ? ? ? ? resize(capacity[capacityIndex]);? ?

? ? ? ? }}

returnret;

}

4网持、從哈希表中查找和修改元素

查找和修改的邏輯基本一致,首先通過 hash 函數(shù)計算元素在數(shù)組中的索引长踊,然后通過此索引去 hashtable 數(shù)組中找對應(yīng) map功舀,最后通過 map 的 put 函數(shù)去修改元素;通過 map 的 containsKey 或者 get 函數(shù)去查找元素身弊;

publicvoidset(K key, V value){TreeMap map = hashtable[hash(key)];if(!map.containsKey(key))thrownewIllegalArgumentException(key +" doesn't exist!");

map.put(key, value);}

publicbooleancontains(K key){returnhashtable[hash(key)].containsKey(key);}

publicVget(K key){returnhash

table[hash(key)].get(key);

}

5辟汰、哈希表完整代碼

importjava.util.TreeMap;

publicclassHashTable, V> {

privatefinalint[] capacity= {53,97,193,389,769,1543,3079,6151,12289,24593,49157,98317,196613,393241,786433,1572869,3145739,6291469,12582917,25165843,50331653,100663319,201326611,402653189,805306457,1610612741};

privatestaticfinalintupperTol=10;privatestaticfinalintlowerTol=2;privateintcapacityIndex=0;

privateTreeMap[]

hashtable;privateintsize;

privateintM;

publicHashTable(){

this.M = capacity[capacityIndex];size =0;

hashtable =newTreeMap[M];

for(inti=0; i < M ; i ++)

hashtable[i] =newTreeMap<>();

}

privateinthash(K key){return(

key.hashCode() &0x7fffffff) % M;

}

publicintgetSize(){

returnsize;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市阱佛,隨后出現(xiàn)的幾起案子帖汞,更是在濱河造成了極大的恐慌,老刑警劉巖凑术,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翩蘸,死亡現(xiàn)場離奇詭異,居然都是意外死亡淮逊,警方通過查閱死者的電腦和手機(jī)催首,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泄鹏,“玉大人郎任,你說我怎么就攤上這事∶” “怎么了涝滴?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長胶台。 經(jīng)常有香客問我歼疮,道長,這世上最難降的妖魔是什么诈唬? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任韩脏,我火速辦了婚禮,結(jié)果婚禮上铸磅,老公的妹妹穿的比我還像新娘赡矢。我一直安慰自己,他們只是感情好阅仔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布吹散。 她就那樣靜靜地躺著,像睡著了一般八酒。 火紅的嫁衣襯著肌膚如雪空民。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機(jī)與錄音界轩,去河邊找鬼画饥。 笑死,一個胖子當(dāng)著我的面吹牛浊猾,可吹牛的內(nèi)容都是我干的抖甘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼葫慎,長吁一口氣:“原來是場噩夢啊……” “哼衔彻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起幅疼,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤米奸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后爽篷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悴晰,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年逐工,在試婚紗的時候發(fā)現(xiàn)自己被綠了铡溪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡泪喊,死狀恐怖棕硫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情袒啼,我是刑警寧澤哈扮,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蚓再,受9級特大地震影響滑肉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜摘仅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一靶庙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧娃属,春花似錦六荒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秩铆,卻和暖如春砚亭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工钠惩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人族阅。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓篓跛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親坦刀。 傳聞我的和親對象是個殘疾皇子愧沟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容