อะไรคือความแตกต่างระหว่าง a HashMap
และ a Hashtable
ใน Java?
มีประสิทธิภาพมากขึ้นสำหรับแอปพลิเคชั่นที่ไม่ได้ทำการเธรด?
ConcurrentMap
คือไม่จำเป็นที่นี่เป็นคำถามที่ว่า“ใช้งานที่ไม่ใช่เกลียว” ความหมายเกลียว / พร้อมกันคือไม่เป็นปัญหา
อะไรคือความแตกต่างระหว่าง a HashMap
และ a Hashtable
ใน Java?
มีประสิทธิภาพมากขึ้นสำหรับแอปพลิเคชั่นที่ไม่ได้ทำการเธรด?
ConcurrentMap
คือไม่จำเป็นที่นี่เป็นคำถามที่ว่า“ใช้งานที่ไม่ใช่เกลียว” ความหมายเกลียว / พร้อมกันคือไม่เป็นปัญหา
คำตอบ:
มีความแตกต่างระหว่างHashMap
และHashtable
ใน Java:
Hashtable
ถูกซิงโครไนซ์ในขณะที่HashMap
ไม่ใช่ สิ่งนี้จะทำให้HashMap
ดีขึ้นสำหรับแอปพลิเคชันที่ไม่ได้ใช้เธรดเนื่องจากวัตถุที่ไม่ซิงโครไนซ์มักจะทำงานได้ดีกว่าซิงโครไนซ์
Hashtable
ไม่อนุญาตให้ใช้null
คีย์หรือค่า HashMap
อนุญาตหนึ่งnull
คีย์และจำนวนnull
ค่าใด ๆ
หนึ่งใน subclasses HashMap เป็นLinkedHashMap
ดังนั้นในกรณีที่คุณต้องการเพื่อย้ำคาดเดาได้ (ซึ่งเป็นคำสั่งแทรกโดยค่าเริ่มต้น), คุณได้อย่างง่ายดายสามารถสลับออกมาหาHashMap
นี้จะไม่เป็นเรื่องง่ายถ้าคุณกำลังใช้LinkedHashMap
Hashtable
HashMap
ตั้งแต่การประสานไม่เป็นปัญหาสำหรับคุณผมอยากแนะนำให้ หากการซิงโครไนซ์กลายเป็นปัญหาคุณอาจดูConcurrentHashMap
ด้วย
Collections.synchronizedMap()
ด้ายปลอดภัยใช้
Hashtable
("การซิงโครไนซ์ทุกวิธีควรดูแลปัญหาการเกิดพร้อมกันใด ๆ !") ทำให้แย่ลงมากสำหรับแอปพลิเคชันแบบเธรด คุณจะดีกว่าเมื่อทำการซิงโครไนซ์ภายนอกHashMap
(และคิดถึงผลที่ตามมา) หรือใช้ConcurrentMap
การนำไปใช้ Bottom line: เหตุผลเดียวที่จะใช้Hashtable
คือเมื่อ API ดั้งเดิม (จากแคลิฟอร์เนีย 1996) ต้องการมัน
โปรดทราบว่าคำตอบจำนวนมากระบุว่า Hashtable ถูกซิงโครไนซ์ ในทางปฏิบัติสิ่งนี้ซื้อคุณน้อยมาก การซิงโครไนซ์อยู่ในวิธีการเข้าถึง / การเปลี่ยนแปลงจะหยุดสองเธรดเพิ่มหรือลบออกจากแผนที่พร้อมกัน แต่ในโลกแห่งความเป็นจริงคุณมักจะต้องประสานเพิ่มเติม
สำนวนที่พบบ่อยมากคือ "ตรวจสอบแล้ววาง" - คือมองหารายการในMap
และเพิ่มถ้ามันไม่ได้อยู่ นี้ไม่ได้อยู่ในทางใดทางหนึ่งงานอะตอมว่าคุณจะใช้หรือHashtable
HashMap
การซิงโครไนซ์อย่างเท่าเทียมกันHashMap
สามารถรับได้โดย:
Collections.synchronizedMap(myMap);
แต่การใช้ตรรกะนี้อย่างถูกต้องคุณจะต้องทำการซิงโครไนซ์เพิ่มเติมของแบบฟอร์ม:
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
แม้ว่าการวนซ้ำHashtable
ของรายการ (หรือที่HashMap
ได้รับจากCollections.synchronizedMap
) จะไม่ปลอดภัยจนกว่าคุณจะป้องกันไม่ให้Map
ถูกแก้ไขผ่านการซิงโครไนซ์เพิ่มเติม
การติดตั้งConcurrentMap
ส่วนต่อประสาน (ตัวอย่างConcurrentHashMap
) แก้ปัญหาบางอย่างด้วยการรวมความหมายของเธรดเซฟเช็คแล้วทำหน้าที่เช่น:
ConcurrentMap.putIfAbsent(key, value);
Hashtable
ถือเป็นรหัสดั้งเดิม ไม่มีอะไรที่เกี่ยวกับเรื่องHashtable
ที่ไม่สามารถทำได้โดยใช้HashMap
หรือดัดแปลงของHashMap
ดังนั้นสำหรับรหัสใหม่ผมไม่เห็นเหตุผลใด ๆ Hashtable
ที่จะกลับไป
คำถามนี้มักถูกถามในการสัมภาษณ์เพื่อตรวจสอบว่าผู้สมัครเข้าใจการใช้ชั้นเรียนที่ถูกต้องหรือไม่และตระหนักถึงทางเลือกอื่น ๆ
HashMap
ระดับคือประมาณเทียบเท่ากับการHashtable
ยกเว้นว่ามันไม่ใช่ตรงกันและ nulls ใบอนุญาต ( HashMap
อนุญาตให้ค่า Null เป็นคีย์และค่าในขณะที่Hashtable
ไม่อนุญาตnull
)HashMap
ไม่รับประกันว่าลำดับของแผนที่จะคงที่ตลอดเวลาHashMap
ไม่ซิงโครไนซ์ในขณะที่Hashtable
ซิงโครไนซ์HashMap
ไม่ปลอดภัยในขณะที่ตัวแจงนับสำหรับHashtable
is ไม่และโยนConcurrentModificationException
หากเธรดอื่นใดแก้ไขแผนที่โครงสร้างโดยการเพิ่มหรือลบองค์ประกอบใด ๆ ยกเว้น วิธีการIterator
ของตัวเอง remove()
แต่นี่ไม่ใช่พฤติกรรมที่รับประกันและจะทำโดย JVM ในความพยายามอย่างดีที่สุดหมายเหตุเกี่ยวกับข้อกำหนดที่สำคัญบางประการ:
Hashtable
จะต้องได้รับการล็อคบนวัตถุในขณะที่คนอื่นจะรอการปลดล็อคset
เมธอดเนื่องจากไม่ได้แก้ไขคอลเล็กชัน "โครงสร้าง" อย่างไรก็ตามถ้าก่อนที่จะโทรset
คอลเลกชันที่ได้รับการแก้ไขโครงสร้างIllegalArgumentException
จะถูกโยนHashMap
สามารถทำข้อมูลให้ตรงกันโดย
Map m = Collections.synchronizeMap(hashMap);
แผนที่แสดงมุมมองคอลเล็กชันแทนที่จะสนับสนุนโดยตรงสำหรับการวนซ้ำผ่านวัตถุการแจงนับ มุมมองคอลเลกชันช่วยเพิ่มความรู้สึกของอินเทอร์เฟซอย่างมากดังที่กล่าวไว้ในส่วนนี้ แผนที่ช่วยให้คุณสามารถวนซ้ำคีย์ค่าหรือคู่คีย์ - ค่า
Hashtable
ไม่มีตัวเลือกที่สาม แผนที่เป็นวิธีที่ปลอดภัยในการลบรายการในระหว่างการทำซ้ำ Hashtable
ไม่ได้. ในที่สุด Map จะแก้ไขข้อบกพร่องเล็กน้อยในHashtable
อินเทอร์เฟซ
Hashtable
มีวิธีการที่เรียกว่า contain ซึ่งจะคืนค่า true ถ้า
Hashtable
มีค่าที่กำหนด ชื่อของคุณคาดหวังวิธีนี้เพื่อกลับจริงถ้ามีคีย์ที่กำหนดเพราะที่สำคัญคือกลไกการเข้าถึงหลักสำหรับHashtable
Hashtable
ส่วนต่อประสานแผนที่จะกำจัดแหล่งที่มาของความสับสนนี้ด้วยการเปลี่ยนชื่อวิธี
containsValue
. นอกจากนี้ช่วยเพิ่มความสอดคล้องอินเตอร์เฟซฯ -
แนวcontainsValue
containsKey
set
HashMap
3) การput(...)
ดำเนินการจะไม่โยนIllegalArgumentException
หากมีการเปลี่ยนแปลงก่อนหน้านี้ 4) ลักษณะการทำงานที่ล้มเหลวอย่างรวดเร็วของHashMap
ยังเกิดขึ้นถ้าคุณเปลี่ยนการแมป 5) พฤติกรรมล้มเหลวอย่างรวดเร็วมีการรับประกัน (สิ่งที่ไม่สามารถรับประกันได้คือพฤติกรรมของ a HashTable
หากคุณทำการปรับเปลี่ยนพร้อมกันพฤติกรรมที่แท้จริงคือ ... คาดเดาไม่ได้)
Hashtable
ไม่รับประกันว่าลำดับขององค์ประกอบแผนที่จะมีเสถียรภาพตลอดเวลาเช่นกัน (คุณจะอาจจะทำให้เกิดความสับสนHashtable
กับLinkedHashMap
.)
thing.set(thing.get() + 1);
ซึ่งบ่อยครั้งมากกว่าที่จะไม่จับมือใหม่ด้วยความประหลาดใจที่ไม่มีการป้องกันอย่างสมบูรณ์โดยเฉพาะอย่างยิ่งถ้าวิธีการget()
และset()
มีการซิงโครไนซ์ หลายคนคาดว่าจะมีเวทย์มนตร์
HashMap
: การใช้Map
อินเทอร์เฟซที่ใช้รหัสแฮชเพื่อจัดทำดัชนีอาร์เรย์
Hashtable
: สวัสดีปี 1998 เรียกว่า พวกเขาต้องการ API คอลเลกชันของพวกเขากลับมา
อย่างจริงจังแม้ว่าคุณจะดีกว่าอยู่ห่างจากHashtable
ทั้งหมด สำหรับแอพพลิเคชั่นที่มีเธรดเดียวคุณไม่ต้องการโอเวอร์เฮดของการซิงโครไนซ์เพิ่มเติม สำหรับแอพที่มีความพร้อมสูงการซิงโครไนซ์หวาดระแวงอาจนำไปสู่ความอดอยากการหยุดชะงักหรือการรวบรวมขยะที่ไม่จำเป็นหยุดชั่วคราว คุณอาจใช้ConcurrentHashMap
แทนทิมฮาวแลนด์แทน
โปรดทราบว่าHashTable
เป็นคลาสดั้งเดิมก่อนที่จะมีการแนะนำ Java Collections Framework (JCF) และได้รับการดัดแปลงในภายหลังเพื่อปรับใช้Map
อินเตอร์เฟส ดังนั้นเป็นและVector
Stack
ดังนั้นให้อยู่ห่างจากพวกเขาในรหัสใหม่เสมอเพราะมีทางเลือกที่ดีกว่าใน JCFเหมือนที่คนอื่น ๆ ชี้ไว้
นี่คือชีทการสะสม Javaที่คุณจะพบว่ามีประโยชน์ สังเกตว่าบล็อกสีเทาประกอบด้วยคลาส HashTable, Vector และ Stack
มีคำตอบที่ดีมากมายที่โพสต์แล้ว ฉันกำลังเพิ่มจุดใหม่ไม่กี่แห่งและสรุปมัน
HashMap
และHashtable
ทั้งสองจะถูกนำมาใช้ในการจัดเก็บข้อมูลในรูปแบบที่สำคัญและความคุ้มค่า ทั้งสองกำลังใช้เทคนิคการแปลงแป้นพิมพ์เพื่อจัดเก็บคีย์ที่ไม่ซ้ำกัน แต่มีความแตกต่างมากมายระหว่างคลาส HashMap และ Hashtable ที่ให้ไว้ด้านล่าง
HashMap
HashMap
ไม่ตรง ไม่ปลอดภัยสำหรับเธรดและไม่สามารถแชร์ระหว่างหลายเธรดได้หากไม่มีรหัสการซิงโครไนซ์ที่เหมาะสม HashMap
อนุญาตหนึ่งคีย์ null และหลายค่า null HashMap
เป็นคลาสใหม่ที่เปิดตัวใน JDK 1.2 HashMap
รวดเร็ว HashMap
ซิงโครไนซ์โดยเรียกรหัสนี้Map m = Collections.synchronizedMap(HashMap);
HashMap
ถูก traversed โดย Iterator HashMap
นั้นล้มเหลวอย่างรวดเร็ว HashMap
สืบทอดคลาส AbstractMap Hashtable
Hashtable
ถูกทำข้อมูลให้ตรงกัน มันปลอดภัยสำหรับเธรดและสามารถแชร์กับหลายเธรดได้ Hashtable
ไม่อนุญาตคีย์หรือค่า Null ใด ๆ Hashtable
เป็นคลาสดั้งเดิม Hashtable
ช้า Hashtable
ถูกซิงโครไนซ์ภายในและไม่สามารถซิงโครไนซ์ได้ Hashtable
ถูก traversed โดย Enumerator และ Iterator Hashtable
ไม่ใช่แบบล้มเหลว Hashtable
สืบทอดคลาสพจนานุกรมอ่านเพิ่มเติมความแตกต่างระหว่าง HashMap และ Hashtable ใน Java คืออะไร?
นอกจากสิ่งที่ izb กล่าวแล้วยังHashMap
อนุญาตให้มีค่า Null ในขณะที่Hashtable
ไม่รองรับ
โปรดทราบด้วยว่าการHashtable
ขยายDictionary
คลาสซึ่งเป็นสถานะJavadocsนั้นล้าสมัยและถูกแทนที่ด้วยMap
อินเตอร์เฟส
ลองดูที่แผนภูมินี้ มันมีการเปรียบเทียบระหว่างโครงสร้างข้อมูลที่แตกต่างกันพร้อมกับและHashMap
Hashtable
การเปรียบเทียบมีความแม่นยำชัดเจนและเข้าใจง่าย
Hashtable
คล้ายกับHashMap
และมีส่วนต่อประสานที่คล้ายกัน ขอแนะนำให้คุณใช้HashMap
เว้นแต่คุณจะต้องการการสนับสนุนสำหรับแอปพลิเคชันรุ่นเก่าหรือคุณต้องการการซิงโครไนซ์เนื่องจากHashtables
วิธีการซิงโครไนซ์ ดังนั้นในกรณีของคุณเนื่องจากคุณไม่ได้ใช้มัลติเธรดHashMaps
เป็นทางออกที่ดีที่สุดของคุณ
ข้อแตกต่างที่สำคัญอีกอย่างหนึ่งระหว่าง hashtable และ hashmap คือ Iterator ใน HashMap นั้นล้มเหลวอย่างรวดเร็วในขณะที่ตัวแจงนับสำหรับ Hashtable ไม่ได้และโยน ConcurrentModificationException หากเธรดอื่นใดแก้ไขแผนที่โครงสร้างโดยการเพิ่มหรือลบองค์ประกอบใด ๆ แต่นี่ไม่ใช่พฤติกรรมที่รับประกันและจะทำโดย JVM ในความพยายามอย่างดีที่สุด "
แหล่งที่มาของฉัน: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
นอกเหนือจากส่วนที่สำคัญอื่น ๆ ที่กล่าวถึงแล้วที่นี่ Collections API (เช่นอินเทอร์เฟซแผนที่) จะถูกแก้ไขตลอดเวลาเพื่อให้สอดคล้องกับส่วนเพิ่มเติม "ล่าสุดและยิ่งใหญ่ที่สุด" ของข้อมูลจำเพาะ Java
ตัวอย่างเช่นเปรียบเทียบการทำซ้ำ Java 5 Map:
for (Elem elem : map.keys()) {
elem.doSth();
}
เมื่อเทียบกับวิธี Hashtable แบบเก่า:
for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
Elem elem = (Elem) en.nextElement();
elem.doSth();
}
ใน Java 1.8 เราได้รับคำสัญญาว่าจะสามารถสร้างและเข้าถึง HashMaps ได้เช่นเดียวกับภาษาสคริปต์เก่า ๆ :
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
อัปเดต:ไม่พวกเขาจะไม่ลงจอดใน 1.8 ... :(
การปรับปรุงการเก็บสะสมของ Project Coin จะเป็นใน JDK8 หรือไม่?
Hashtable
ทำข้อมูลให้ตรงกันในขณะที่HashMap
ไม่ ที่ทำให้ช้ากว่าHashtable
Hashmap
สำหรับแอพที่ไม่ใช่เธรดให้ใช้HashMap
เนื่องจากเป็นแอปที่ทำงานเหมือนกัน
HashTable ได้รับการซิงโครไนซ์ถ้าคุณใช้ในเธรดเดียวคุณสามารถใช้HashMapซึ่งเป็นเวอร์ชันที่ไม่ซิงโครไนซ์ วัตถุที่ไม่ซิงโครไนซ์มักจะมีประสิทธิภาพมากกว่าเล็กน้อย โดยวิธีถ้าหลายเธรดเข้าถึง HashMap พร้อมกันและอย่างน้อยหนึ่งเธรดที่ปรับเปลี่ยนการแมปแบบโครงสร้างนั้นจะต้องซิงโครไนส์ภายนอก Youn สามารถตัดแผนที่ที่ไม่ซิงโครไนซ์ในแผนที่ที่มีการซิงโครไนซ์ได้
Map m = Collections.synchronizedMap(new HashMap(...));
HashTable สามารถมีวัตถุที่ไม่ใช่ null เป็นคีย์หรือเป็นค่า HashMap สามารถมีได้หนึ่งคีย์ null และค่า null
iterators ที่ส่งกลับโดยแผนที่จะล้มเหลวได้อย่างรวดเร็วหากแผนที่มีการแก้ไขโครงสร้างตลอดเวลาหลังจาก iterator จะถูกสร้างขึ้นในทางใด ๆ ยกเว้นผ่านวิธีการลบ iterator ของตัวเองที่ iterator ConcurrentModificationException
จะโยน ดังนั้นในการเผชิญกับการเปลี่ยนแปลงที่เกิดขึ้นพร้อมกันตัววนซ้ำล้มเหลวอย่างรวดเร็วและหมดจดแทนที่จะเสี่ยงต่อการกระทำตามอำเภอใจไม่กำหนดเวลาในอนาคต ในขณะที่การแจงนับที่ส่งคืนโดยคีย์และองค์ประกอบของ Hashtable นั้นไม่ได้ล้มเหลวอย่างรวดเร็ว
HashTable และ HashMap เป็นสมาชิกของJava Collections Framework (ตั้งแต่ Java 2 แพลตฟอร์ v1.2, HashTable ได้รับการดัดแปลงเพื่อติดตั้งส่วนต่อประสานแผนที่)
HashTable ถือเป็นรหัสดั้งเดิมเอกสารแนะนำให้ใช้ConcurrentHashMapแทน Hashtable หากต้องการการใช้งานพร้อมกันที่ปลอดภัยต่อเธรดสูง
HashMap ไม่รับประกันการสั่งซื้อคืนองค์ประกอบ สำหรับ HashTable ฉันเดาว่าเหมือนกัน แต่ฉันไม่แน่ใจทั้งหมดฉันไม่พบแหล่งที่มาที่ระบุชัดเจน
HashMap
และHashtable
มีความแตกต่างของอัลกอริทึมที่สำคัญเช่นกัน ไม่มีใครพูดถึงเรื่องนี้มาก่อนนั่นคือสาเหตุที่ฉันนำมันมาใช้ HashMap
จะสร้างตารางแฮชที่มีกำลังสองขนาดเพิ่มขึ้นแบบไดนามิกเพื่อให้คุณมีองค์ประกอบได้มากถึงแปดองค์ประกอบ (การชนกัน) ในที่ฝากข้อมูลใด ๆ และจะกระตุ้นองค์ประกอบให้ดีสำหรับประเภทองค์ประกอบทั่วไป อย่างไรก็ตามการHashtable
ใช้งานนั้นให้การควบคุม hashing ที่ดีกว่าและดีกว่าถ้าคุณรู้ว่าคุณกำลังทำอะไรอยู่นั่นคือคุณสามารถแก้ไขขนาดของตารางโดยใช้หมายเลขที่ใกล้เคียงที่สุดกับขนาดโดเมนของคุณซึ่งจะทำให้ประสิทธิภาพดีกว่า HashMap สำหรับบางกรณี
แยกจากความแตกต่างที่ชัดเจนที่กล่าวถึงอย่างกว้างขวางในคำถามนี้ฉันเห็น Hashtable เป็นรถ "ไดรฟ์แบบแมนนวล" ที่คุณสามารถควบคุมการแฮชและ HashMap ได้ดีกว่าในฐานะ "ไดรฟ์อัตโนมัติ" ที่ทำงานได้ดี
จากข้อมูลที่นี่ฉันขอแนะนำให้ไปกับ HashMap ฉันคิดว่าข้อได้เปรียบที่ใหญ่ที่สุดคือ Java จะป้องกันไม่ให้คุณแก้ไขมันในขณะที่คุณกำลังวนซ้ำมันจนกว่าคุณจะทำมันผ่านตัววนซ้ำ
เอCollection
- บางครั้งเรียกว่าภาชนะบรรจุ - เป็นเพียงวัตถุที่จัดกลุ่มหลายองค์ประกอบเป็นหน่วยเดียว Collection
s ใช้เพื่อจัดเก็บเรียกใช้จัดการและสื่อสารข้อมูลรวม เฟรมเวิร์กคอลเล็กชันWเป็นสถาปัตยกรรมแบบครบวงจรสำหรับการแสดงและจัดการคอลเลกชัน
กระบวนการHashMap
JDK1.2
และ Hashtable JDK1.0
ทั้งสองถูกใช้เพื่อแสดงกลุ่มของวัตถุที่แสดงเป็น<Key, Value>
คู่ แต่ละ<Key, Value>
คู่เรียกว่าEntry
วัตถุ คอลเลกชันของรายการจะเรียกวัตถุของและHashMap
Hashtable
กุญแจในคอลเลกชันจะต้องไม่ซ้ำกันหรือโดดเด่น [เนื่องจากใช้เพื่อดึงค่าที่แม็พคีย์เฉพาะ ค่าในคอลเลกชันสามารถทำซ้ำ]
«สมาชิก Superclass, Legacy และ Collection Framework
Hashtable เป็นคลาสดั้งเดิมที่นำมาใช้JDK1.0
ซึ่งเป็นคลาสย่อยของคลาส Dictionary จากJDK1.2
Hashtable ได้รับการออกแบบใหม่เพื่อใช้งานอินเทอร์เฟซแผนที่เพื่อทำให้สมาชิกของกรอบงานการรวบรวม HashMap เป็นสมาชิกของ Java JDK1.2
เก็บกรอบทางด้านขวาจากจุดเริ่มต้นของการเปิดตัวใน HashMap เป็นคลาสย่อยของคลาส AbstractMap
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
« กำลังการผลิตเริ่มต้นและตัวประกอบภาระ
ความจุคือจำนวนที่เก็บข้อมูลในตารางแฮชและความจุเริ่มต้นเป็นเพียงความจุ ณ เวลาที่สร้างตารางแฮช โปรดทราบว่าตารางแฮชเปิดอยู่: ในกรณีของ " hash
collision
" ถังเก็บข้อมูลเดียวจะเก็บหลายรายการซึ่งจะต้องค้นหาตามลำดับ ตัวประกอบภาระคือการวัดความเต็มของตารางแฮชที่ได้รับก่อนที่ความจุจะเพิ่มขึ้นโดยอัตโนมัติ
HashMap สร้างตารางแฮชว่างเปล่าที่มีความจุเริ่มต้นเริ่มต้น(16)และปัจจัยการโหลดเริ่มต้น (0.75) โดยที่ Hashtable สร้าง hashtable ว่างเปล่าด้วยความจุเริ่มต้นเริ่มต้น(11)และอัตราส่วนตัวคูณ / อัตราส่วนการเติม (0.75)
« การดัดแปลงโครงสร้างในกรณีที่มีการชนกันของแฮช
HashMap
, Hashtable
ในกรณีของการชนกันของกัญชาที่พวกเขาเก็บรายการแผนที่ในรายการเชื่อมโยง จาก Java8 สำหรับHashMap
linked list of entries to a balanced tree
ถ้าถังกัญชาเติบโตเกินกว่าเกณฑ์ที่กำหนดถังที่จะเปลี่ยนจาก ซึ่งปรับปรุงประสิทธิภาพกรณีที่เลวร้ายที่สุดจาก O (n) ถึง O (log n) ในขณะที่แปลงรายการเป็นต้นไม้ไบนารี hashcode จะใช้เป็นตัวแปรการแยกสาขา หากมีแฮชโค้ดที่แตกต่างกันสองอันในที่เก็บข้อมูลเดียวกันอันที่หนึ่งจะถือว่าใหญ่กว่าและไปทางขวาของต้นไม้และอีกอันหนึ่งอยู่ทางซ้าย แต่เมื่อแฮชโค้ดทั้งสองมีค่าเท่ากันHashMap
สมมติว่าคีย์นั้นเปรียบได้และเปรียบเทียบคีย์เพื่อกำหนดทิศทางเพื่อให้สามารถรักษาลำดับไว้ได้ มันเป็นวิธีที่ดีที่จะทำให้คีย์ของเทียบเคียงHashMap
ในการเพิ่มรายการหากขนาดถังถึงTREEIFY_THRESHOLD = 8
แปลงรายการที่เชื่อมโยงของรายการไปยังทรีแบบสมดุลในการลบรายการที่น้อยกว่าTREEIFY_THRESHOLD
และมากที่สุดUNTREEIFY_THRESHOLD = 6
จะแปลงทรีแบบสมดุลให้กลับเป็นรายการที่ลิงก์ Java 8 SRC , stackpost
«การ รวบรวมซ้ำเพื่อรับชมล้มเหลวเร็วและไม่ปลอดภัย
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iterator
เป็นธรรมชาติที่ล้มเหลวอย่างรวดเร็ว นั่นคือมันจะโยน ConcurrentModificationException ถ้าคอลเลกชันมีการแก้ไขในขณะที่ทำซ้ำอื่น ๆ กว่ามันเป็นวิธีการลบ () ของตัวเอง ในกรณีที่Enumeration
ไม่ปลอดภัยในธรรมชาติ มันจะไม่ส่งข้อยกเว้นใด ๆ หากมีการแก้ไขคอลเล็กชันในขณะที่วนซ้ำ
ตามเอกสาร API ของ Java, Iterator เป็นที่ต้องการมากกว่าการแจงนับ
หมายเหตุ:ฟังก์ชันการทำงานของอินเทอร์เฟซการแจงนับซ้ำโดยอินเทอร์เฟซ Iterator นอกจากนี้ Iterator เพิ่มการดำเนินการลบทางเลือกและมีชื่อวิธีการที่สั้นกว่า การนำไปใช้ใหม่ควรพิจารณาใช้ Iterator ในการตั้งค่าการแจงนับ
ในJava 5 ได้แนะนำ ConcurrentMap Interface : ConcurrentHashMap
- การใช้งานที่มีประสิทธิภาพสูงพร้อมกันซึ่งConcurrentMap
ได้รับการสนับสนุนโดยตารางแฮช การนำไปใช้งานนี้จะไม่บล็อกเมื่อทำการค้นคืนและอนุญาตให้ไคลเอ็นต์เลือกระดับการทำงานพร้อมกันสำหรับการอัพเดต มันมีวัตถุประสงค์เพื่อเป็นดรอปแทนสำหรับHashtable
: นอกเหนือจากการดำเนินการConcurrentMap
จะสนับสนุนทุกวิธีการ "ดั้งเดิม" Hashtable
เฉพาะ
HashMapEntry
ค่า s แต่ละค่ามีความผันผวนดังนั้นจึงมั่นใจได้ว่ามีความสอดคล้องของเม็ดละเอียดสำหรับการดัดแปลงแก้ไขและการอ่านตามมา การอ่านแต่ละครั้งสะท้อนถึงการอัปเดตที่เสร็จสมบูรณ์ล่าสุด
Iterator และ Enumerations นั้นไม่ปลอดภัย - สะท้อนสถานะในบางจุดตั้งแต่การสร้างตัววนซ้ำ / การแจงนับ สิ่งนี้ช่วยให้สามารถอ่านและแก้ไขพร้อมกันได้ในราคาที่ลดลงอย่างสม่ำเสมอ พวกเขาจะไม่โยน ConcurrentModificationException อย่างไรก็ตามตัววนซ้ำได้รับการออกแบบให้ใช้งานได้ครั้งละหนึ่งเธรดเท่านั้น
เหมือนHashtable
แต่แตกต่างจากHashMap
ชั้นนี้ไม่อนุญาตให้ null ที่จะนำมาใช้เป็นคีย์หรือค่า
public static void main(String[] args) {
//HashMap<String, Integer> hash = new HashMap<String, Integer>();
Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
//ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();
new Thread() {
@Override public void run() {
try {
for (int i = 10; i < 20; i++) {
sleepThread(1);
System.out.println("T1 :- Key"+i);
hash.put("Key"+i, i);
}
System.out.println( System.identityHashCode( hash ) );
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
new Thread() {
@Override public void run() {
try {
sleepThread(5);
// ConcurrentHashMap traverse using Iterator, Enumeration is Fail-Safe.
// Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
sleepThread(1);
System.out.println("T2 : "+ e.nextElement());
}
// HashMap traverse using Iterator, Enumeration is Fail-Fast.
/*
for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
sleepThread(1);
System.out.println("T2 : "+ it.next());
// ConcurrentModificationException at java.util.Hashtable$Enumerator.next
}
*/
/*
Set< Entry<String, Integer> > entrySet = hash.entrySet();
Iterator< Entry<String, Integer> > it = entrySet.iterator();
Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
while( entryEnumeration.hasMoreElements() ) {
sleepThread(1);
Entry<String, Integer> nextElement = entryEnumeration.nextElement();
System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
//java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
// at java.util.HashMap$EntryIterator.next
// at java.util.Collections$3.nextElement
}
*/
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
try {
unmodifiableMap.put("key4", "unmodifiableMap");
} catch (java.lang.UnsupportedOperationException e) {
System.err.println("UnsupportedOperationException : "+ e.getMessage() );
}
}
static void sleepThread( int sec ) {
try {
Thread.sleep( 1000 * sec );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
« Null Keys และ Null Values
HashMap
อนุญาตหนึ่งคีย์ว่างสูงสุดหนึ่งคีย์และจำนวนค่า null ใด ๆ ในกรณีที่Hashtable
ไม่อนุญาตให้ใช้แม้แต่คีย์ null เดียวและค่า null หากคีย์หรือค่าว่างเป็นโมฆะก็จะโยน NullPointerException ตัวอย่าง
« ซิงโครไนซ์เธรดอย่างปลอดภัย
Hashtable
ถูกซิงโครไนซ์ภายใน ดังนั้นจึงปลอดภัยมากที่จะใช้Hashtable
ในแอปพลิเคชันแบบมัลติเธรด โดยที่HashMap
ไม่ถูกซิงโครไนซ์ภายใน ดังนั้นจึงไม่ปลอดภัยที่จะใช้HashMap
ในแอปพลิเคชันแบบมัลติเธรดโดยไม่มีการซิงโครไนซ์ภายนอก คุณสามารถซิงโครไนซ์ภายนอกHashMap
โดยใช้Collections.synchronizedMap()
วิธีการ
« ประสิทธิภาพ
ในฐานะที่Hashtable
จะตรงภายในนี้จะทำให้ช้ากว่าเล็กน้อยHashtable
HashMap
@ดู
สำหรับแอพที่มีเธรดคุณมักจะสามารถใช้ ConcurrentHashMap- ได้ตามความต้องการด้านประสิทธิภาพ
1. Hashmap
และHashTable
เก็บรหัสและค่า
2. สามารถเก็บหนึ่งที่สำคัญเป็นHashmap
ไม่สามารถเก็บnull
Hashtable
null
3. HashMap
ไม่ได้ซิงโครไนซ์ แต่Hashtable
ซิงโครไนซ์
4. HashMap
สามารถทำข้อมูลให้ตรงกันกับCollection.SyncronizedMap(map)
Map hashmap = new HashMap();
Map map = Collections.SyncronizedMap(hashmap);
นอกเหนือจากความแตกต่างที่กล่าวมาแล้วก็ควรจะตั้งข้อสังเกตว่าตั้งแต่ Java 8 HashMap
แบบไดนามิกแทนที่โหนด (รายการที่เชื่อมโยง) ที่ใช้ในแต่ละถังมี TreeNodes (ต้นไม้แดงดำ) ดังนั้นแม้ว่าชนกัญชาสูงอยู่กรณีที่เลวร้ายที่สุดเมื่อ การค้นหาคือ
O (เข้าสู่ระบบ (n)) สำหรับHashMap
Vs O (n) Hashtable
ใน
* การปรับปรุงดังกล่าวยังไม่ได้ถูกนำไปใช้Hashtable
แต่เพียงเพื่อHashMap
, และLinkedHashMap
ConcurrentHashMap
FYI ปัจจุบัน
TREEIFY_THRESHOLD = 8
: ถ้าที่เก็บข้อมูลมีมากกว่า 8 โหนดรายการที่เชื่อมโยงจะถูกเปลี่ยนเป็นโครงสร้างที่สมดุลUNTREEIFY_THRESHOLD = 6
: เมื่อที่เก็บข้อมูลมีขนาดเล็กเกินไป (เนื่องจากการลบหรือปรับขนาด) ต้นไม้จะถูกแปลงกลับไปเป็นรายการที่เชื่อมโยงมีความแตกต่างพื้นฐาน 5 ประการด้วย HashTable และ HashMaps
ผลงานเล็ก ๆ ของฉัน:
สิ่งแรกและสำคัญที่สุดที่แตกต่างระหว่าง
Hashtable
และHashMap
คือHashMap
ไม่ปลอดภัยในขณะที่Hashtable
เป็นคอลเลกชันของเธรดที่ปลอดภัยแตกต่างที่สำคัญระหว่างสอง
Hashtable
และHashMap
เป็นผลการดำเนินงานตั้งแต่จะไม่ตรงกันมันทำงานได้ดีกว่าHashMap
Hashtable
ข้อแตกต่างที่สามของ
Hashtable
vsHashMap
คือHashtable
คลาสที่ล้าสมัยและคุณควรใช้ConcurrentHashMap
แทนHashtable
Java
HashMap: เป็นคลาสที่มีอยู่ในแพ็คเกจ java.util และใช้เพื่อจัดเก็บองค์ประกอบในรูปแบบคีย์และค่า
Hashtable: เป็นคลาสดั้งเดิมที่ได้รับการยอมรับในกรอบการรวบรวม
HashTableเป็นคลาสดั้งเดิมใน jdk ที่ไม่ควรใช้อีกต่อไป แทนที่การใช้งานของมันด้วยConcurrentHashMap หากคุณไม่ต้องการความปลอดภัยของเธรดให้ใช้HashMapซึ่งไม่ใช่threadsafeแต่เร็วกว่าและใช้หน่วยความจำน้อยกว่า
Hashtable
ทำข้อมูลให้ตรงกันในขณะที่HashMap
ไม่HashMap
คือไม่ปลอดภัยในขณะที่การแจงนับสำหรับการHashtable
ไม่ได้ หากคุณเปลี่ยนแผนที่ในขณะที่วนซ้ำคุณจะรู้HashMap
อนุญาตให้มีค่า Null ในขณะที่Hashtable
ไม่HashMap และ HashTable
1) Hashtable และ Hashmap ใช้ส่วนต่อประสาน java.util.Map 2) ทั้ง Hashmap และ Hashtable เป็นชุดที่ใช้แฮช และทำงานเกี่ยวกับการคร่ำครวญ ดังนั้นสิ่งเหล่านี้จึงมีความคล้ายคลึงกันของ HashMap และ HashTable
1) ความแตกต่างแรกคือ HashMap ไม่ปลอดภัยในขณะที่ด้าย HashTable เป็น ThreadSafe
2) HashMap มีประสิทธิภาพดีกว่าเพราะมันไม่ปลอดภัย ในขณะที่ประสิทธิภาพการทำงานของ Hashtable ที่ชาญฉลาดนั้นไม่ได้ดีกว่าเพราะมันปลอดภัยสำหรับเธรด ดังนั้นหลายเธรดไม่สามารถเข้าถึง Hashtable ได้ในเวลาเดียวกัน
Hashtable:
Hashtableเป็นโครงสร้างข้อมูลที่เก็บค่าของคู่คีย์ - ค่าไว้ ไม่อนุญาตให้มีค่าว่างสำหรับทั้งคีย์และค่า คุณจะได้รับNullPointerException
ถ้าคุณเพิ่มค่าเป็นศูนย์ มันจะทำข้อมูลให้ตรงกัน ดังนั้นมันมาพร้อมกับราคา มีเธรดเดียวเท่านั้นที่สามารถเข้าถึงHashTableในเวลาใดเวลาหนึ่ง
ตัวอย่าง :
import java.util.Map;
import java.util.Hashtable;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states= new Hashtable<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); //will throw NullPointerEcxeption at runtime
System.out.println(states.get(1));
System.out.println(states.get(2));
// System.out.println(states.get(3));
}
}
HashMap:
HashMapเหมือนกับHashtableแต่ก็ยอมรับคู่ค่าคีย์ จะช่วยให้เป็นโมฆะสำหรับทั้งกุญแจและค่า ประสิทธิภาพการทำงานที่ดีขึ้นจะดีกว่าเพราะมันเป็นHashTable
unsynchronized
ตัวอย่าง:
import java.util.HashMap;
import java.util.Map;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states = new HashMap<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); // Okay
states.put(null,"UK");
System.out.println(states.get(1));
System.out.println(states.get(2));
System.out.println(states.get(3));
}
}
HashMap
ถูกจำลองและใช้งานได้ในGWT client code
ขณะที่Hashtable
ไม่ใช่
หัวข้อเก่าและคลาสสิกเพียงต้องการเพิ่มบล็อกที่มีประโยชน์นี้ซึ่งอธิบายสิ่งนี้:
http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/
บล็อกโดย Manish Chhabra
ความแตกต่างที่สำคัญ 5 ประการระหว่าง HashMap และ Hashtable
ทั้ง HashMap และ Hashtable ใช้อินเตอร์เฟส java.util.Map แต่มีความแตกต่างบางประการที่ผู้พัฒนา Java ต้องเข้าใจเพื่อเขียนโค้ดที่มีประสิทธิภาพมากขึ้น ในฐานะที่เป็นแพลตฟอร์ม Java 2 v1.2 ชั้น Hashtable ได้รับการดัดแปลงเพื่อใช้งานแผนที่อินเตอร์เฟสทำให้เป็นสมาชิกของ Java Collections Framework
หนึ่งในความแตกต่างที่สำคัญระหว่าง HashMap และ Hashtable คือ HashMap นั้นไม่ได้ทำการซิงโครไนซ์ในขณะที่ Hashtable ถูกซิงโครไนซ์ซึ่งหมายความว่า Hashtable นั้นปลอดภัยสำหรับเธรดและสามารถแชร์ระหว่างหลายเธรดได้ แต่ HashMap Java 5 แนะนำ ConcurrentHashMap ซึ่งเป็นทางเลือกของ Hashtable และให้ความสามารถในการขยายที่ดีกว่า Hashtable ใน Java.Synchronized หมายความว่ามีเพียงเธรดเดียวเท่านั้นที่สามารถแก้ไขตารางแฮชได้ ณ จุดเดียว โดยทั่วไปหมายความว่าเธรดใด ๆ ก่อนที่จะทำการอัปเดตบน hashtable จะต้องได้รับการล็อกบนวัตถุในขณะที่คนอื่นจะรอการปลดล็อค
คลาส HashMap นั้นเทียบเท่ากับ Hashtable ยกเว้นว่าอนุญาตให้เป็นโมฆะ (HashMap อนุญาตให้มีค่า Null เป็นคีย์และค่าในขณะที่ Hashtable ไม่อนุญาตให้มีค่า Null)
ความแตกต่างที่สำคัญที่สามระหว่าง HashMap กับ Hashtable คือ Iterator ใน HashMap นั้นเป็นตัววนซ้ำที่ล้มเหลวอย่างรวดเร็วในขณะที่ตัวแจงนับสำหรับ Hashtable ไม่ได้และโยน ConcurrentModificationException หากเธรดอื่นใดแก้ไขแผนผังโครงสร้างโดยลบหรือลบองค์ประกอบใด ๆ ) วิธี. แต่นี่ไม่ใช่พฤติกรรมที่รับประกันและจะทำโดย JVM ในความพยายามอย่างดีที่สุด นี่คือความแตกต่างที่สำคัญระหว่างการแจงนับและ Iterator ใน Java
ความแตกต่างที่น่าสังเกตอีกอย่างหนึ่งระหว่าง Hashtable และ HashMap คือเนื่องจากความปลอดภัยของเธรดและการซิงโครไนซ์ Hashtable นั้นช้ากว่า HashMap มากหากใช้ในสภาพแวดล้อมเธรดเดี่ยว ดังนั้นหากคุณไม่ต้องการการซิงโครไนซ์และ HashMap จะใช้งานโดยเธรดเดียวเท่านั้นจึงจะใช้งาน Hashtable ใน Java ได้
HashMap ไม่รับประกันว่าคำสั่งของแผนที่จะคงที่ตลอดเวลา
โปรดทราบว่า HashMap สามารถซิงโครไนซ์ได้
Map m = Collections.synchronizedMap(hashMap);
โดยสรุปมีความแตกต่างที่สำคัญระหว่าง Hashtable และ HashMap ใน Java เช่นความปลอดภัยของเธรดและความเร็วและจากนั้นใช้ Hashtable เฉพาะเมื่อคุณต้องการความปลอดภัยของเธรดอย่างแน่นอนหากคุณใช้ Java 5 ให้พิจารณาใช้ ConcurrentHashMap ใน Java
HashMapและHashtableทั้งคู่ใช้เพื่อเก็บข้อมูลในรูปแบบของคีย์และค่า ทั้งสองกำลังใช้เทคนิคการแปลงแป้นพิมพ์เพื่อจัดเก็บคีย์ที่ไม่ซ้ำกัน มีความแตกต่างมากมายระหว่างคลาส HashMap และ Hashtable ที่ให้ไว้ด้านล่าง