1. Hashtable เป็นคลาสย่อยของพจนานุกรม
คัดลอกรหัสรหัส ดังต่อไปนี้:
Hashtable ระดับสาธารณะ <K,V>
ขยายพจนานุกรม<K,V>
ใช้ Map<K,V>, Cloneable, java.io.Serializable
แฮชแมป:
คัดลอกรหัสรหัส ดังต่อไปนี้:
HashMap คลาสสาธารณะ <K,V>
ขยาย AbstractMap<K,V>
ใช้ Map<K,V>, Cloneable, Serializable
HashMap และ Hashtable เป็นทั้งคลาสการใช้งานของอินเทอร์เฟซ Map;
2. วิธีการใน Hashtable เป็นแบบซิงโครนัส () แต่วิธีการใน HashMap จะไม่ซิงโครนัสตามค่าเริ่มต้น กล่าวคือในแอปพลิเคชันแบบมัลติเธรด Hashtable สามารถใช้งานได้อย่างปลอดภัยโดยไม่ต้องดำเนินการพิเศษ สำหรับ HashMap จำเป็นต้องมีกลไกการซิงโครไนซ์เพิ่มเติม แต่ปัญหาการซิงโครไนซ์ของ HashMap สามารถแก้ไขได้ด้วยวิธีคอลเลกชันแบบคงที่:
คัดลอกรหัสรหัส ดังต่อไปนี้:
สาธารณะคงที่ <K,V> แผนที่ <K,V> synchronizedMap (แผนที่ <K,V> m)
เมธอดนี้ส่งคืนแผนที่ที่ซิงโครไนซ์ ซึ่งหมายความว่าแผนที่ที่ส่งคืนนั้นปลอดภัยสำหรับเธรด ควรสังเกตว่าเมื่อวนซ้ำบนแผนที่ที่ส่งคืน คุณต้องซิงโครไนซ์ด้วยตนเองบนแผนที่ที่ส่งคืน ไม่เช่นนั้นจะทำให้เกิดพฤติกรรมที่ไม่ได้กำหนดไว้:
คัดลอกรหัสรหัส ดังต่อไปนี้:
แผนที่ m = Collections.synchronizedMap (ใหม่ HashMap ());
-
Set s = m.keySet(); // ไม่จำเป็นต้องอยู่ในบล็อกที่ซิงโครไนซ์
-
synchronized(m) { // ซิงโครไนซ์กับ m ไม่ใช่ s!
Iterator i = s.iterator(); // ต้องอยู่ในบล็อกที่ซิงโครไนซ์
ในขณะที่ (i.hasNext())
ฟู(i.next());
-
3. ใน HashMap null สามารถใช้เป็นคีย์ได้ และมีคีย์ดังกล่าวเพียงคีย์เดียวเท่านั้น โดยสามารถมีได้ตั้งแต่หนึ่งคีย์ขึ้นไปซึ่งค่าที่สอดคล้องกันเป็น null เมื่อเมธอด get() ส่งกลับค่า null อาจหมายความว่าไม่มีคีย์อยู่ใน HashMap หรืออาจหมายความว่าค่าที่สอดคล้องกับคีย์นั้นเป็น null ก็ได้ ดังนั้น ใน HashMap จึงไม่สามารถใช้เมธอด get() เพื่อพิจารณาว่ามีคีย์บางตัวอยู่ใน HashMap หรือไม่ แต่ควรใช้เมธอด containsKey() เพื่อกำหนด ค่าคีย์ของ Hashtable ไม่สามารถเป็นค่าว่างได้ มิฉะนั้น: java.lang.NullPointerException
4.HashTable ใช้การแจงนับ และ HashMap ใช้ Iterator
ข้างต้นเป็นเพียงความแตกต่างเพียงผิวเผินและการนำไปใช้ก็แตกต่างกันมากเช่นกัน
5. ขนาดเริ่มต้นของอาร์เรย์แฮชใน HashTable คือ 11 และวิธีการเพิ่มคือเก่า*2+1 ขนาดเริ่มต้นของอาร์เรย์แฮชใน HashMap คือ 16 และต้องเป็นเลขชี้กำลังของ 2
6. การใช้ค่าแฮชจะแตกต่างกัน HashTable ใช้ hashCode ของออบเจ็กต์โดยตรงดังนี้
คัดลอกรหัสรหัส ดังต่อไปนี้:
int hash = key.hashCode();
ดัชนี int = (แฮช & 0x7FFFFFFFF) % tab.length;
HashMap คำนวณค่าแฮชใหม่และใช้ AND แทนโมดูลัส เช่น วิธีการใส่ของ HashMap:
คัดลอกรหัสรหัส ดังต่อไปนี้:
ใส่สาธารณะ V (คีย์ K, ค่า V) {
ถ้า (คีย์ == null)
ส่งคืน putForNullKey (ค่า);
int hash = hash(key.hashCode());
int i = indexFor (แฮช, table.length);
สำหรับ (รายการ <K,V> e = table[i]; e != null; e = e.next) {
วัตถุเค;
ถ้า (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = มูลค่า;
e.recordAccess(นี้);
คืนค่าเก่า;
-
-
modCount++;
addEntry(แฮช, คีย์, ค่า, i);
กลับเป็นโมฆะ;
-
คัดลอกรหัสรหัส ดังต่อไปนี้:
แฮช int แบบคงที่ (int h) {
// ฟังก์ชั่นนี้ช่วยให้แน่ใจว่า hashCodes ที่แตกต่างกันเท่านั้น
// ค่าทวีคูณคงที่ในแต่ละตำแหน่งบิตมีขอบเขต
// จำนวนการชน (ประมาณ 8 ที่ปัจจัยโหลดเริ่มต้น)
ชม ^= (ชม >>> 20) ^ (ชม >>> 12);
กลับ h ^ (h >>> 7) ^ (h >>> 4);
-
คัดลอกรหัสรหัส ดังต่อไปนี้:
ดัชนี int แบบคงที่สำหรับ (int h, ความยาว int) {
กลับ h & (ความยาว -1);
-