HashMap鐨勫疄鐜板亣瀹歨ash鍑芥暟灝嗗悇涓厓绱犳紜垎甯冨湪鍚勬《涔嬮棿錛屽彲涓哄熀鏈搷浣滐紙濡俫et()鍜宻et()錛夋彁渚涚ǔ瀹氱殑鎬ц兘錛岃凱浠i泦鍚堣鍥炬墍闇鐨勬椂闂翠笌HashMap 瀹炰緥鐨?#8220;瀹歸噺”錛堟《鐨勬暟閲忥級鍙婂叾澶у皬錛堥敭-鍊兼槧灝勫叧緋繪暟錛夌殑鍜屾垚姣斾緥銆傛墍浠ワ紝濡傛灉榪唬鎬ц兘寰堥噸瑕侊紝鍒欎笉瑕佸皢鍒濆瀹歸噺璁劇疆寰楀お楂橈紙鎴栧皢鍔犺澆鍥犲瓙璁劇疆寰楀お浣庯級銆?錛堟敞錛氳繖孌靛悓HashSet寰堢浉浼鹼紝鍏跺疄HashSet鏄熀鏈琀ashMap瀹炵幇鐨勶紝鎵浠ュ湪鎬ц兘鐨勬帶鍒朵笂涔熶竴鏍鳳級
HashMap 鐨勫疄渚嬫湁涓や釜鍙傛暟褰卞搷鍏舵ц兘錛氬垵濮嬪閲忓拰鍔犺澆鍥犲瓙銆傚閲忔槸鍝堝笇琛ㄤ腑妗剁殑鏁伴噺錛屽垵濮嬪閲忓彧鏄搱甯岃〃鍦ㄥ垱寤烘椂鐨勫閲忋傚姞杞藉洜瀛愭槸鍝堝笇琛ㄥ湪鍏跺閲忚嚜鍔ㄥ鍔犱箣鍓嶅彲浠ヨ揪鍒板婊$殑涓縐嶅昂搴︺傚綋鍝堝笇琛ㄤ腑鐨勬潯鐩暟瓚呭嚭浜嗗姞杞藉洜瀛愪笌褰撳墠瀹歸噺鐨勪箻縐椂錛岄氳繃璋冪敤 rehash 鏂規硶灝嗗閲忕炕鍊嶃侶ashMap鐨勯粯璁ゅ垵濮嬪閲忔槸16錛岄粯璁ゅ姞杞藉洜瀛愭槸0.75錛岃繖鏍鳳紝褰揌ashMap閲岀殑鍏冪礌瓚呰繃16*0.75鍗?2鏃訛紝璋冪敤rehash鏂規硶錛屼嬌瀹歸噺澧為暱涓鍊嶃?/p>
閫氬父錛岄粯璁ゅ姞杞藉洜瀛?(.75) 鍦ㄦ椂闂村拰絀洪棿鎴愭湰涓婂姹備竴縐嶆姌琛楓傚姞杞藉洜瀛愯繃楂樿櫧鐒跺噺灝戜簡絀洪棿寮閿錛屼絾鍚屾椂涔熷鍔犱簡鏌ヨ鎴愭湰錛堝湪澶у鏁?nbsp;HashMap綾葷殑鎿嶄綔涓紝鍖呮嫭 get 鍜?nbsp;put 鎿嶄綔錛岄兘鍙嶆槧浜嗚繖涓鐐癸級銆傚湪璁劇疆鍒濆瀹歸噺鏃跺簲璇ヨ冭檻鍒版槧灝勪腑鎵闇鐨勬潯鐩暟鍙婂叾鍔犺澆鍥犲瓙錛屼互渚挎渶澶ч檺搴﹀湴闄嶄綆 rehash 鎿嶄綔嬈℃暟銆傚鏋滃垵濮嬪閲忓ぇ浜庢渶澶ф潯鐩暟闄や互鍔犺澆鍥犲瓙錛屽垯涓嶄細鍙戠敓 rehash 鎿嶄綔銆?/p>
濡傛灉寰堝鏄犲皠鍏崇郴瑕佸瓨鍌ㄥ湪 HashMap 瀹炰緥涓紝鍒欑浉瀵逛簬鎸夐渶鎵ц鑷姩鐨?rehash 鎿嶄綔浠ュ澶ц〃鐨勫閲忔潵璇達紝浣跨敤瓚沖澶х殑鍒濆瀹歸噺鍒涘緩瀹冨皢浣垮緱鏄犲皠鍏崇郴鑳芥洿鏈夋晥鍦板瓨鍌ㄣ?nbsp;
娉ㄦ剰錛屾瀹炵幇涓嶆槸鍚屾鐨勩?/strong> 濡傛灉澶氫釜綰跨▼鍚屾椂璁塊棶姝ゆ槧灝勶紝鑰屽叾涓嚦灝戜竴涓嚎紼嬩粠緇撴瀯涓婁慨鏀逛簡璇ユ槧灝勶紝鍒欏畠蹇呴』 淇濇寔澶栭儴鍚屾銆傦紙緇撴瀯涓婄殑淇敼鏄寚娣誨姞鎴栧垹闄や竴涓垨澶氫釜鏄犲皠鍏崇郴鐨勬搷浣滐紱浠呮敼鍙樹笌瀹炰緥宸茬粡鍖呭惈鐨勯敭鍏寵仈鐨勫間笉鏄粨鏋勪笂鐨勪慨鏀廣傦級榪欎竴鑸氳繃瀵硅嚜鐒跺皝瑁呰鏄犲皠鐨勫璞¤繘琛屽悓姝ユ搷浣滄潵瀹屾垚銆傚鏋滀笉瀛樺湪榪欐牱鐨勫璞★紝鍒欏簲璇ヤ嬌鐢?nbsp;Collections.synchronizedMap 鏂規硶鏉?#8220;鍖呰”璇ユ槧灝勩傛渶濂藉湪鍒涘緩鏃跺畬鎴愯繖涓鎿嶄綔錛屼互闃叉瀵規槧灝勮繘琛屾剰澶栫殑涓嶅悓姝ヨ闂紝濡備笅鎵紺猴細
Map m = Collections.synchronizedMap(new HashMap(...));
鐢辨墍鏈夋綾葷殑“闆嗗悎瑙嗗浘鏂規硶”鎵榪斿洖鐨勮凱浠e櫒閮芥槸蹇熷け璐ョ殑錛氬湪榪唬鍣ㄥ垱寤轟箣鍚庯紝濡傛灉浠庣粨鏋勪笂瀵規槧灝勮繘琛屼慨鏀癸紝闄ら潪閫氳繃榪唬鍣?/p>
鑷韓鐨?remove 鎴?add 鏂規硶錛屽叾浠栦換浣曟椂闂翠換浣曟柟寮忕殑淇敼錛岃凱浠e櫒閮藉皢鎶涘嚭 ConcurrentModificationException 銆傚洜姝わ紝闈㈠騫跺彂
鐨勪慨鏀癸紝榪唬鍣ㄥ緢蹇氨浼氬畬鍏ㄥけ璐ワ紝鑰屼笉鍐掑湪灝嗘潵涓嶇‘瀹氱殑鏃墮棿浠繪剰鍙戠敓涓嶇‘瀹氳涓虹殑椋庨櫓銆?
娉ㄦ剰錛岃凱浠e櫒鐨勫揩閫熷け璐ヨ涓轟笉鑳藉緱鍒頒繚璇侊紝涓鑸潵璇達紝瀛樺湪涓嶅悓姝ョ殑騫跺彂淇敼鏃訛紝涓嶅彲鑳戒綔鍑轟換浣曞潥鍐崇殑淇濊瘉銆傚揩閫熷け璐ヨ凱浠e櫒灝芥渶澶?/p>
鍔姏鎶涘嚭 ConcurrentModificationException 銆傚洜姝わ紝緙栧啓渚濊禆浜庢寮傚父紼嬪簭鐨勬柟寮忔槸閿欒鐨勶紝姝g‘鍋氭硶鏄細榪唬鍣ㄧ殑蹇熷け璐ヨ涓哄簲
璇ヤ粎鐢ㄤ簬媯嫻嬬▼搴忛敊璇?em style="font-style: italic; ">銆?/em> HashMap鐨勬瀯閫犲嚱鏁幫細
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);// Find a power of 2 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor);
table = new Entry[capacity];
init();
}鍙互鐪嬪嚭錛屽綋鐢熸垚HashMap瀵硅薄鏃訛紝濡傛灉initialCapacity鐨勬暟鍊兼瘮杈冨ぇ鏃訛紝capacity 浼氳璧嬩簬絳変簬鎴栧ぇ浜巌nitialCapacity 鐨勫鹼紝鐒跺悗
鍒涘緩涓涓湁capacity 涓狤ntry瀵硅薄鐨則able鏁扮粍錛屾墍浠nitialCapacity鐨勬暟鍊間笉鑳藉お澶э紝鍚﹀垯浼氱敓鎴愭瘮杈冨ぇ鐨勬暟緇則able錛屽崰鐢ㄦ瘮杈冨ぇ鐨勫簲鐢ㄥ唴
瀛橈紝閫犳垚鍐呭瓨嫻垂銆?/p>
HashMap鐨勯粯璁ゆ瀯閫犲嚱鏁幫細
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR;
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
table = new Entry[DEFAULT_INITIAL_CAPACITY];
init();
}榛樿鏋勯犲嚱鏁伴噷鐨勫垵濮嬪閲忎負16錛屽姞杞藉洜瀛愪負0.75錛岃繖鏍蜂細鐢熸垚鍚湁16*0.75=12涓狤ntry瀵硅薄鐨勬暟緇則able錛屽綋HashMap閲岀殑鍏冪礌鏁?/p>
閲忚秴榪?2涓椂錛屼細灝咹ashMap鐨勫閲忕炕1鍊嶏紝鐢熸垚鍖呭惈32涓狤ntry瀵硅薄鐨勬暟緇勩?/p>
put鏂規硶錛?/span>
public V put(K key, V value) {
K k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
if (e.hash == hash && eq(k, e.key)) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, k, value, i);
return null;
}
K k = maskNull(key);榪欒鏄垽鏂璳ey鏄惁涓簄ull錛屽鏋滀負null錛屽垯榪斿洖涓涓潤鎬佺殑K錛圤bject錛夊璞″仛涓洪敭鍊鹼紝榪欏氨鏄疕ashMap涓轟粈涔堝厑璁竛ull閿瓨鍦ㄧ殑鍘熷洜銆?/span>
int hash = hash(k);
int i = indexFor(hash, table.length);
榪欒繛緇殑涓ゆ灝辨槸 HashMap 鏈鐗涚殑鍦版柟錛佺爺絀跺畬鎴戦兘姹楅浜嗭紝鍏朵腑 hash 灝辨槸閫氳繃 key 榪欎釜Object鐨?hashcode 榪涜 hash錛岀劧鍚庨氳繃 indexFor 鑾峰緱鍦∣bject table鐨勭儲寮曞箋?/span>
table錛燂紵錛熶笉瑕佹儕璁訛紝鍏跺疄HashMap涔熺涓嶅埌鍝噷鍘伙紝瀹冨氨鏄敤 table 鏉ユ斁鐨勩傛渶鐗涚殑灝辨槸鐢?hash 鑳芥紜殑榪斿洖绱㈠紩銆傚叾涓殑hash綆楁硶錛屾垜璺烰DK鐨勪綔鑰?Doug 鑱旂郴榪囷紝浠栧緩璁垜鐪嬬湅銆奣he art of programing vol3銆嬪彲鎭ㄧ殑鏄紝鎴戜箣鍓嶅氨涓鐩村湪鎵撅紝鎴戦兘鎵句笉鍒幫紝浠栬繖鏍蜂竴鎻愶紝鎴戝氨鏇村姞鎬ヤ簡錛屽彲鎯滃彛琚嬬┖絀哄晩錛侊紒錛?br />
涓嶇煡閬撳ぇ瀹舵湁娌℃湁鐣欐剰 put 鍏跺疄鏄竴涓湁榪斿洖鐨勬柟娉曪紝瀹冧細鎶婄浉鍚岄敭鍊肩殑 put 瑕嗙洊鎺夊茍榪斿洖鏃х殑鍊鹼紒濡備笅鏂規硶褰誨簳璇存槑浜?HashMap 鐨勭粨鏋勶紝鍏跺疄灝辨槸涓涓〃鍔犱笂鍦ㄧ浉搴斾綅緗殑Entry鐨勯摼琛細
for (Entry e = table; e != null; e = e.next) {
if (e.hash == hash && eq(k, e.key)) {
Object oldvalue = e.value;
e.value = value; //鎶婃柊鐨勫艱祴浜堢粰瀵瑰簲閿箋?br />
e.recordAccess(this); //絀烘柟娉曪紝鐣欏緟瀹炵幇
return oldvalue; //榪斿洖鐩稿悓閿肩殑瀵瑰簲鐨勬棫鐨勫箋?br />
}
}
modCount++; //緇撴瀯鎬ф洿鏀圭殑嬈℃暟
addEntry(hash, k, value, i); //娣誨姞鏂板厓绱狅紝鍏抽敭鎵鍦紒
return null; //娌℃湁鐩稿悓鐨勯敭鍊艱繑鍥?br />
}
鎴戜滑鎶婂叧閿殑鏂規硶鎷垮嚭鏉ュ垎鏋愶細
void addEntry(int hash, Object key, Object value, int bucketIndex) {
table[bucketIndex] = new Entry(hash, key, value, table[bucketIndex]);
鍥犱負 hash 鐨勭畻娉曟湁鍙兘浠や笉鍚岀殑閿兼湁鐩稿悓鐨刪ash鐮佸茍鏈夌浉鍚岀殑table绱㈠紩錛屽錛歬ey錛?#8220;33”鍜宬ey錛漁bject g鐨刪ash閮芥槸錛?901334錛岄偅瀹冪粡榪噄ndexfor涔嬪悗鐨勭儲寮曚竴瀹氶兘涓篿錛岃繖鏍峰湪new鐨勬椂鍊欒繖涓狤ntry鐨刵ext灝變細鎸囧悜榪欎釜鍘熸湰鐨?table錛屽啀鏈変笅涓涓篃濡傛錛屽艦鎴愪竴涓摼琛紝鍜宲ut鐨勫驚鐜瀹歟.next鑾峰緱鏃х殑鍊箋傚埌榪欓噷錛孒ashMap鐨勭粨鏋勶紝澶у涔熷崄鍒嗘槑鐧戒簡鍚э紵
if (size++ >= threshold) //榪欎釜threshold灝辨槸鑳藉疄闄呭綰崇殑閲?br />
resize(2 * table.length); //瓚呭嚭榪欎釜瀹歸噺灝變細灝哋bject table閲嶆瀯
鎵璋撶殑閲嶆瀯涔熶笉紲烇紝灝辨槸寤轟竴涓袱鍊嶅ぇ鐨則able錛堟垜鍦ㄥ埆鐨勮鍧涗笂鐪嬪埌鏈変漢璇存槸涓ゅ嶅姞1錛屾妸鎴戦獥浜嗭級錛岀劧鍚庡啀涓涓釜indexfor榪涘幓錛佹敞鎰忥紒錛佽繖灝辨槸鏁堢巼錛侊紒濡傛灉浣犺兘璁╀綘鐨凥ashMap涓嶉渶瑕侀噸鏋勯偅涔堝嬈★紝鏁堢巼浼氬ぇ澶ф彁楂橈紒
璇村埌榪欓噷涔熷樊涓嶅浜嗭紝get姣攑ut綆鍗曞緱澶氾紝澶у錛屼簡瑙ut錛実et涔熷樊涓嶄簡澶氬皯浜嗐傚浜巆ollections鎴戞槸璁や負錛屽畠鏄傚悎騫挎硾鐨勶紝褰撲笉瀹?鍏ㄩ傚悎鐗規湁鐨勶紝濡傛灉澶у鐨勭▼搴忛渶瑕佺壒孌婄殑鐢ㄩ旓紝鑷繁鍐欏惂錛屽叾瀹炲緢綆鍗曘傦紙浣滆呮槸榪欐牱璺熸垜璇寸殑錛屼粬榪樺緩璁垜鐢↙inkedHashMap,鎴戠湅浜嗘簮鐮佷互鍚庡彂 鐜幫紝LinkHashMap鍏跺疄灝辨槸緇ф壙HashMap鐨勶紝鐒跺悗override鐩稿簲鐨勬柟娉曪紝鏈夊叴瓚g殑鍚屼漢錛岃嚜宸眑ooklook錛夊緩涓?Object table錛屽啓鐩稿簲鐨勭畻娉曪紝灝眔k鍟︺?br />
涓句釜渚嬪瓙鍚э紝鍍?Vector錛宭ist 鍟婁粈涔堢殑鍏跺疄閮藉緢綆鍗曪紝鏈澶氬氨澶氫簡鐨勫悓姝ョ殑澹版槑錛屽叾瀹炲鏋滆瀹炵幇鍍廣ector閭g錛屾彃鍏ワ紝鍒犻櫎涓嶅鐨勶紝鍙互鐢ㄤ竴涓狾bject table鏉ュ疄鐜幫紝鎸夌儲寮曞瓨鍙栵紝娣誨姞絳夈?br />
濡傛灉鎻掑叆錛屽垹闄ゆ瘮杈冨鐨勶紝鍙互寤轟袱涓狾bject table錛岀劧鍚庢瘡涓厓绱犵敤鍚湁next緇撴瀯鐨勪竴涓猼able瀛橈紝濡傛灉瑕佹彃鍏ュ埌i錛屼絾鏄痠宸茬粡鏈夊厓绱狅紝鐢╪ext榪炶搗鏉ワ紝鐒跺悗size錛嬶紜錛屽茍鍦ㄥ彟涓涓猼able璁板綍鍏朵綅緗?/span>