浜虹墿錛?/em>
鐜嬪皬鑳栵細鎬у埆錛氱敺銆傜▼搴忓憳錛屽伐浣滅粡楠?/em>1 year銆傜埍濂斤細鍚冭倝銆佺數鐜┿侀┈灝忚姳銆傜壒鎶錛氬悆鑲変笉鐢ㄨ冭檻鑳冪殑瀹歸噺銆?/em>
椹皬鑺憋細鎬у埆錛氬コ銆傚鐢燂紝宸ヤ綔緇忛獙0 year銆傜埍濂斤細铔嬬硶銆佽嚟緹庛佺帇灝忚儢銆傜壒鎶錛氳兘澶熼檷鏈嶇帇灝忚儢……
/**2011騫?/em>2鏈堬紝鐢靛獎銆婂皢鐖辨儏榪涜鍒板簳銆嬬伀寰椾笉寰椾簡銆傚懆鏈紝灝忚儢涔熼櫔鐫灝忚姳鍘葷湅榪欓儴鐢靛獎銆傛斁鏄犱腑錛屽皬鑺辮褰辯墖涓殑闈栧摜鍝ュ拰鏉滄媺鎷夋劅鍔ㄧ殑涓娌撶硦娑傦紝鑰屽皬鑳栧垯蹇冮噷鏆楄嚜鍚庢倲娌℃湁涔頒竴琚嬪ぇ鐖嗙背鑺辨潵鎵撳彂榪欐棤鑱婄殑鏃墮棿銆傚獎鐗囩粨鏉燂紝灝忚姳宸茬粡鏄薊娑曚竴鎶婃唱涓鎶婏紝灝忚儢涔熷彧鏈夎妯′綔鏍峰湴鎶藉姩浜嗗嚑涓嬮薊瀛愶紝涓蹇冨彧鎯崇潃涓浼氬効鏄悆楹﹀綋鍔寵繕鏄繀鑳滃銆?/em>*/
鍥炲埌瀹朵腑錛屽皬鑳栧拰灝忚姳鍚勮嚜鐜╃潃鐢佃剳銆?/em>
灝忚姳錛氳儢瀛愶紝浣犵煡閬?/em>Hashtable鍜?/em>HashMap鐨勫尯鍒悧錛?/em>
灝忚儢錛氱暐鐭ャ?/em>
灝忚姳錛?#8230;…瑁呬粈涔堬紒錛佺粰鎴戣璁詫紒錛侊紒
灝忚儢錛氬ソ鐨?#8230;…
絎竴涓尯鍒氨鍏堟潵璇磋緇ф壙鍏崇郴鍚с?/strong>
濡傛灉浣犲湪baidu閲実oogle涓涓嬶紙鎶鏈被鏂囩珷鐨勬悳绱㈣繕鏄帹鑽恎oogle錛夛紝浼氬彂鐜扮綉涓婄殑澶ц嚧璇存硶涓?#8220;鐢變簬Java鍙戝睍鐨勫巻鍙插師鍥犮侶ashtable鏄熀浜庨檲鏃х殑Dictionary綾葷殑錛孒ashMap鏄疛ava 1.2寮曡繘鐨凪ap鎺ュ彛鐨勪竴涓疄鐜般?#8221;鐩稿悓銆傝繖縐嶈娉曟病鏈夐敊錛屼絾鏄儢瀛愯寰椾笉澶熷噯紜紝鐗瑰埆鏄浜庢垜浠繖縐嶅ぇ浼楄彍楦熸潵璇達紝濡傛灉涓嶅幓娣辯┒鐨勮瘽錛屽彲鑳藉氨浼氶犳垚涓浜涚悊瑙d笂鐨勫樊寮傘傜畝鍗曠殑璁や負Hashtable娌℃湁緇ф壙Map鎺ュ彛銆傝儢瀛愪箣鍓嶅氨鐘繃榪欐牱鐨勯敊璇紙鑳栧瓙鎵胯鑷繁絎紝鏄湡絎?#8230;…錛?銆?/p>
灝忚姳錛氶偅浣犳庝箞鐭ラ亾瀹冧滑涓や釜鍚勮嚜鐨勭戶鎵垮叧緋誨憿錛熻儢瀛愩?/em>
鎴戜滑鍙互鍙傝冧竴涓嬫渶鏂扮殑JDK1.6鐨勬簮鐮侊紝鐪嬬湅榪欎袱涓被鐨勫畾涔夛細
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable {…} public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {…}
鍙互鐪嬪埌hashtable涔熸槸緇ф壙浜哅ap鎺ュ彛銆傚畠浠殑涓嶅悓鏄疕ashtable錛坰ince JDK1.0錛夊氨緇ф壙浜咲ictionary榪欎釜鎶借薄綾伙紝鑰孒ashMap錛坰ince JDK1.2錛夌戶鎵跨殑鍒欐槸AbstractMap榪欎釜鎶借薄綾匯傚洜涓哄湪Hashtable涓湅鍒扮戶鎵縈ap鍚庢墍瀹炵幇鐨勬柟娉曟槸JDK1.2鐗堟湰鏃跺姞涓婂幓鐨勶紝鎵浠ヨ儢瀛愮寽鎯沖彲鑳芥槸鍦↗DK 1.2寮鍙戞椂Sun宸ョ▼甯堝嚭浜庣粺涓鐨勮冭檻浣垮緱Hashtable涔熺戶鎵夸簡Map鎺ュ彛銆?/p>
灝忚姳錛氬摝錛屽師鏉?/em>JDK婧愮爜榪樿兘鐪嬪嚭鏉ヨ繖涓?/em>
灝忚儢錛?#8230;…鍚庨潰榪樿兘鐪嬪嚭鏇村涓滆タ鐨勩?/em>
灝忚姳錛氬ソ鏈熷緟鍟娿?/em>
絎簩涓尯鍒垜浠粠鍚屾鍜屽茍鍙戞т笂鏉ヨ璇村畠浠袱涓殑涓嶅悓銆?/strong>
鍙互閫氳繃榪欎袱涓被寰楁簮鐮佹潵鍒嗘瀽錛孒ashtable涓殑涓昏鏂規硶閮藉仛浜嗗悓姝ュ鐞嗭紝鑰孒ashMap鍒欐病鏈夈傚彲浠ヨHashtable鍦ㄩ粯璁ゆ儏鍐墊敮鎸佸悓姝ワ紝鑰孒ashMap鍦ㄩ粯璁ゆ儏鍐典笅鏄笉鏀寔鐨勩傛垜浠湪澶氱嚎紼嬪茍鍙戠殑鐜涓嬶紝鍙互鐩存帴浣跨敤Hashtable錛屼絾鏄浣跨敤HashMap鐨勮瘽灝辮鑷繁澧炲姞鍚屾澶勭悊浜嗐傚HashMap鐨勫悓姝ュ鐞嗗彲浠ヤ嬌鐢–ollections綾繪彁渚涚殑synchronizedMap闈欐佹柟娉曪紱鎴栬呯洿鎺ヤ嬌鐢↗DK5.0涔嬪悗鎻愪緵鐨刯ava.util.concurrent鍖呴噷鐨凜oncurrentHashMap綾匯?/p>
灝忚儢錛?/em>synchronizedMap闈欐佹柟娉曞拰ConcurrentHashMap綾繪垜浼氫互鍚庡啀緇欎綘璇︾粏璁蹭竴涓嬬殑銆傝偉濠嗐?/em>
灝忚姳錛氫綘淇濊瘉鍟娿傞挜鍖欏繕浜嗕綘鐭ラ亾鍚庢灉鐨勩?/em>
灝忚儢錛氬ソ鐨?#8230;…
絎笁涓尯鍒氨鏄畠浠浜?/strong>null鍊肩殑澶勭悊鏂瑰紡浜嗐?/strong>
鎴戜滑渚濈劧鑳藉浠庢簮浠g爜涓緱鐭ワ紝Hashtable涓紝key鍜寁alue閮戒笉鍏佽鍑虹幇null鍊箋?/p>
public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; //… }
鍦ㄦ垜浠嬌鐢ㄤ笂闈㈢殑鏂規硶鏃訛紝濡傚弬鏁皏alue涓簄ull錛屽彲浠ヤ粠浠g爜涓洿鎺ョ湅鍑虹▼搴忎細鎶涘嚭NullPointerException錛涜屽湪key涓簄ull鏃訛紝鍒欎細鍦?#8220;int hash = key.hashCode();“榪欐璁$畻Hash鍊肩殑榪囩▼涓姏鍑篘ullPointerException銆?/span>鑰屽湪鍦℉ashMap涓紝鍏佽null浣滀負key瀛樺湪錛屽茍涓斿拰鍏朵粬key鐨勭壒鎬т竴鏍鳳紝榪欐牱鐨刵ull鍊糼ey鍙兘鏈変竴涓紱鍙﹀HashMap鍏佽澶氫釜value涓簄ull銆傝繖鏍峰ぇ瀹跺氨瑕佹敞鎰忎簡錛?nbsp;HashMap涓氨涓嶈兘鐢╣et(key)鏂規硶鏉ュ垽鏂璈ashMap涓槸鍚﹀瓨鍦ㄦ煇涓猭ey錛屽洜涓簐alue涓簄ull鍜屼笉瀛樺湪璇ey鐨凟ntry閮戒細榪斿洖null鍊鹼紝鑰屽簲璇ョ敤containsKey()鏂規硶鏉ュ垽鏂簡銆?/p>
緇撴灉錛?/span> HashMap瀵逛簬null鍊糼ey鐨勫鐞嗙綉涓婃湁璇?#8220;null 鐢╪ew Object()鏉ヤ唬鏇匡紝鍏禘ntry.hashCode=0,鑰屼笖鍦ㄥ彇鍑虹殑鏃跺欒繕浼氳繕鍥瀗ull鐨勩?#8221;鑳栧瓙鎴戝湪璇誨彇婧愮爜鐨勮繃紼嬩腑鐪嬪埌浜唍ull鍊肩殑hash鍊肩‘瀹炴槸0 錛堝唴閮ㄥ疄鐜扮殑鏁扮粍涓殑index涔熸槸錛夛紝浣嗘槸鑳藉姏鏈夐檺娌℃湁鐪嬪埌杞負new Object()鐨勮繃紼嬨?/p>
灝忚姳錛?鍘熸潵hashMap鐨?/em>containsKey榪樻湁榪欎箞涓櫡闃憋紝浠ュ悗鑲ュ﹩瑕佸皬蹇冧簡銆?/em> 絎洓涓笉鍚屽氨鏄畠浠袱涓?/strong>Hash鍊肩殑鑾峰彇鏂瑰紡浜嗐?/strong> 榪樻槸閫氳繃婧愪唬鐮佹簮浠g爜錛孒ashtable鏄洿鎺ヤ嬌鐢╧ey瀵硅薄鐨刪ash鍊箋?/p>
鑰孒ashMap鍒欐槸鍒╃敤key瀵硅薄鐨刪ash鍊奸噸鏂拌綆椾竴涓柊鐨刪ash鍊箋?/p>
灝忚姳錛氳儢瀛愶紝閮界敤浜?/em>hash綆楁硶錛屼綘緇欐垜璁茶Hash綆楁硶鍚с?/em> 灝忚儢錛氬棷……浠ュ悗鐨勶紝浠婂ぉ鎴戞瘮杈冨繖錛堝叾瀹炴槸涓嶄細錛夈?/em> 灝忚姳錛氫綘鏄笉鏄笉浼氬晩錛熷樋鍢匡紙鍧忕瑧錛夈?/em> 灝忚儢錛氫粈涔堜笉浼?#8230;…璋堜笅涓璇濋…… 絎簲涓笉鍚屽氨鏄?/strong>Hashtable鍜?/strong>HashMap瀹冧滑涓や釜鍐呴儴瀹炵幇鏂瑰紡鐨勬暟緇勭殑鍒濆澶у皬鍜屾墿瀹圭殑鏂瑰紡銆?/strong> HashMap涓唴閮ㄦ暟緇勭殑鍒濆瀹歸噺鏄?6錛?鍔犺澆鍥犲瓙涓?.75錛岃屼笖鏁扮粍瀹歸噺澧炲鍚庝篃瑕佹槸2鎸囨暟嬈″箓錛?/p>
HashTable涓殑鍐呴儴鏁扮粍鐨勫垵濮嬪閲忔槸11錛屽姞杞藉洜瀛愪篃鏄?.75鏁扮粍鐨勫瀹規柟寮忎負錛坥ldCapacity * 2 + 1錛? 絎叚涓笉鍚屾垜浠粠瀹冧滑涓や釜閬嶅巻鏂瑰紡鐨勫唴閮ㄥ疄鐜頒笂鏉ヨ銆?/strong> Hashtable HashMap閮戒嬌鐢ㄤ簡 Iterator銆傝岀敱浜庡巻鍙插師鍥狅紝Hashtable榪樹嬌鐢ㄤ簡Enumeration鐨勬柟寮?銆?/p>
灝忚姳錛?/em>Iterator鍜?/em>Enumeration鐨勫尯鍒槸浠涔堝晩錛熺粰鎴戣璁層?/em> 灝忚儢錛氭垜涓嶆槸璇存垜娌℃湁鏃墮棿鍢涳紝涓嬪洖鐨勩?/em> 灝忚姳錛氭垜閮借涓嬫潵錛岀渷寰椾綘緇欐垜娣瘋繃鍘匯傦紙鎷胯搗絎斿紑濮嬭璐︿腑錛?/em> 灝忚儢錛?#8230;…錛堢揣寮狅級 絎竷涓笉鍚屾椂瀹冧滑鐨勬嫹璐濇瀯閫犲嚱鏁扮殑涓嶅悓銆?/strong> 渚濈劧鏄氳繃鏌ョ湅婧愮爜錛屽彲浠ュ彂鐜板畠浠袱涓浜庢嫹璐濆嚱鏁板垵濮嬪閲忕殑涓嶅悓鍊箋?/p>
HashMap鐨勫疄鐜版槸錛?/p>
鑰孒ashtable鐨勫疄鐜版槸錛?/p>
灝忚儢錛氫粖澶╄鐨勫凡緇忓緢澶氫簡銆傛垜鏈夌偣楗夸簡錛岃偉濠嗐?/em> 灝忚姳錛氱湅浣犱粖澶╃殑琛ㄧ幇榪欎箞濂姐傝蛋錛屽甫浣犲幓鍚冪儰鑲夊幓銆?/em> 灝忚儢錛氬搱鍝堬紝鑲ュ﹩涓囧瞾銆?/em> PS:涓嬮潰鎵撶畻鍐欑殑涓浜涗笢瑗?/p>
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class TestCase {
public static void main(String[] args) {
Map<Integer,String> hashMap = new HashMap<Integer,String>();
hashMap.put(0, null);
hashMap.put(1, "one");
hashMap.put(2, "two");
hashMap.put(null, "null");
for(Entry<Integer, String> e : hashMap.entrySet()) {
System.out.println("Key: " + e.getKey() + " -- Value: " + e.getValue());
}
System.out.println(hashMap.get(0));
System.out.println(hashMap.get(4));
System.out.println("Contains key 0 ? :" + hashMap.containsKey(0));
System.out.println("Contains key 4 ? :" + hashMap.containsKey(4));
System.out.println("Contains value null ? :" + hashMap.containsValue(null));
}
}
Key: null -- Value: null
Key: 0 -- Value: null
Key: 1 -- Value: one
Key: 2 -- Value: two
null
null
Contains key 0 ? :true
Contains key 4 ? :false
Contains value null ? :true
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry tab[] = table;
int hash = key.hashCode();//hashcode
int index = (hash & 0x7FFFFFFF) % tab.length;
//…
}
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());//hashcode
int i = indexFor(hash, table.length);
//…
}
static int hash(int h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 16;
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
public Hashtable() {
this(11, 0.75f);
}
protected void rehash() {
int oldCapacity = table.length;
Entry[] oldMap = table;
int newCapacity = oldCapacity * 2 + 1;
//…
}
public HashMap(Map<? extends K, ? extends V> m) {
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
putAllForCreate(m);
}
public Hashtable(Map<? extends K, ? extends V> t) {
this(Math.max(2*t.size(), 11), 0.75f);
putAll(t);
}