อะไรคือความแตกต่างระหว่าง 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 นี้จะไม่เป็นเรื่องง่ายถ้าคุณกำลังใช้LinkedHashMapHashtable
HashMapตั้งแต่การประสานไม่เป็นปัญหาสำหรับคุณผมอยากแนะนำให้ หากการซิงโครไนซ์กลายเป็นปัญหาคุณอาจดูConcurrentHashMapด้วย
Collections.synchronizedMap()ด้ายปลอดภัยใช้
Hashtable("การซิงโครไนซ์ทุกวิธีควรดูแลปัญหาการเกิดพร้อมกันใด ๆ !") ทำให้แย่ลงมากสำหรับแอปพลิเคชันแบบเธรด คุณจะดีกว่าเมื่อทำการซิงโครไนซ์ภายนอกHashMap(และคิดถึงผลที่ตามมา) หรือใช้ConcurrentMapการนำไปใช้ Bottom line: เหตุผลเดียวที่จะใช้Hashtableคือเมื่อ API ดั้งเดิม (จากแคลิฟอร์เนีย 1996) ต้องการมัน
โปรดทราบว่าคำตอบจำนวนมากระบุว่า Hashtable ถูกซิงโครไนซ์ ในทางปฏิบัติสิ่งนี้ซื้อคุณน้อยมาก การซิงโครไนซ์อยู่ในวิธีการเข้าถึง / การเปลี่ยนแปลงจะหยุดสองเธรดเพิ่มหรือลบออกจากแผนที่พร้อมกัน แต่ในโลกแห่งความเป็นจริงคุณมักจะต้องประสานเพิ่มเติม
สำนวนที่พบบ่อยมากคือ "ตรวจสอบแล้ววาง" - คือมองหารายการในMapและเพิ่มถ้ามันไม่ได้อยู่ นี้ไม่ได้อยู่ในทางใดทางหนึ่งงานอะตอมว่าคุณจะใช้หรือHashtableHashMap
การซิงโครไนซ์อย่างเท่าเทียมกัน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ไม่ปลอดภัยในขณะที่ตัวแจงนับสำหรับHashtableis ไม่และโยน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. นอกจากนี้ช่วยเพิ่มความสอดคล้องอินเตอร์เฟซฯ -
แนวcontainsValuecontainsKey
set HashMap3) การ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อินเตอร์เฟส ดังนั้นเป็นและVectorStack
ดังนั้นให้อยู่ห่างจากพวกเขาในรหัสใหม่เสมอเพราะมีทางเลือกที่ดีกว่าใน 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ไม่ ที่ทำให้ช้ากว่าHashtableHashmap
สำหรับแอพที่ไม่ใช่เธรดให้ใช้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- บางครั้งเรียกว่าภาชนะบรรจุ - เป็นเพียงวัตถุที่จัดกลุ่มหลายองค์ประกอบเป็นหน่วยเดียว Collections ใช้เพื่อจัดเก็บเรียกใช้จัดการและสื่อสารข้อมูลรวม เฟรมเวิร์กคอลเล็กชันWเป็นสถาปัตยกรรมแบบครบวงจรสำหรับการแสดงและจัดการคอลเลกชัน
กระบวนการHashMap JDK1.2และ Hashtable JDK1.0ทั้งสองถูกใช้เพื่อแสดงกลุ่มของวัตถุที่แสดงเป็น<Key, Value>คู่ แต่ละ<Key, Value>คู่เรียกว่าEntryวัตถุ คอลเลกชันของรายการจะเรียกวัตถุของและHashMap Hashtableกุญแจในคอลเลกชันจะต้องไม่ซ้ำกันหรือโดดเด่น [เนื่องจากใช้เพื่อดึงค่าที่แม็พคีย์เฉพาะ ค่าในคอลเลกชันสามารถทำซ้ำ]
«สมาชิก Superclass, Legacy และ Collection Framework
Hashtable เป็นคลาสดั้งเดิมที่นำมาใช้JDK1.0ซึ่งเป็นคลาสย่อยของคลาส Dictionary จากJDK1.2Hashtable ได้รับการออกแบบใหม่เพื่อใช้งานอินเทอร์เฟซแผนที่เพื่อทำให้สมาชิกของกรอบงานการรวบรวม 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 { ... }
« กำลังการผลิตเริ่มต้นและตัวประกอบภาระ
ความจุคือจำนวนที่เก็บข้อมูลในตารางแฮชและความจุเริ่มต้นเป็นเพียงความจุ ณ เวลาที่สร้างตารางแฮช โปรดทราบว่าตารางแฮชเปิดอยู่: ในกรณีของ " hashcollision" ถังเก็บข้อมูลเดียวจะเก็บหลายรายการซึ่งจะต้องค้นหาตามลำดับ ตัวประกอบภาระคือการวัดความเต็มของตารางแฮชที่ได้รับก่อนที่ความจุจะเพิ่มขึ้นโดยอัตโนมัติ
HashMap สร้างตารางแฮชว่างเปล่าที่มีความจุเริ่มต้นเริ่มต้น(16)และปัจจัยการโหลดเริ่มต้น (0.75) โดยที่ Hashtable สร้าง hashtable ว่างเปล่าด้วยความจุเริ่มต้นเริ่มต้น(11)และอัตราส่วนตัวคูณ / อัตราส่วนการเติม (0.75)
« การดัดแปลงโครงสร้างในกรณีที่มีการชนกันของแฮช
HashMap, Hashtableในกรณีของการชนกันของกัญชาที่พวกเขาเก็บรายการแผนที่ในรายการเชื่อมโยง จาก Java8 สำหรับHashMaplinked 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จะตรงภายในนี้จะทำให้ช้ากว่าเล็กน้อยHashtableHashMap
@ดู
สำหรับแอพที่มีเธรดคุณมักจะสามารถใช้ ConcurrentHashMap- ได้ตามความต้องการด้านประสิทธิภาพ
1. HashmapและHashTableเก็บรหัสและค่า
2. สามารถเก็บหนึ่งที่สำคัญเป็นHashmap ไม่สามารถเก็บnullHashtablenull
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, และLinkedHashMapConcurrentHashMap
FYI ปัจจุบัน
TREEIFY_THRESHOLD = 8 : ถ้าที่เก็บข้อมูลมีมากกว่า 8 โหนดรายการที่เชื่อมโยงจะถูกเปลี่ยนเป็นโครงสร้างที่สมดุลUNTREEIFY_THRESHOLD = 6 : เมื่อที่เก็บข้อมูลมีขนาดเล็กเกินไป (เนื่องจากการลบหรือปรับขนาด) ต้นไม้จะถูกแปลงกลับไปเป็นรายการที่เชื่อมโยงมีความแตกต่างพื้นฐาน 5 ประการด้วย HashTable และ HashMaps
ผลงานเล็ก ๆ ของฉัน:
สิ่งแรกและสำคัญที่สุดที่แตกต่างระหว่าง
HashtableและHashMapคือHashMapไม่ปลอดภัยในขณะที่Hashtableเป็นคอลเลกชันของเธรดที่ปลอดภัยแตกต่างที่สำคัญระหว่างสอง
HashtableและHashMapเป็นผลการดำเนินงานตั้งแต่จะไม่ตรงกันมันทำงานได้ดีกว่าHashMapHashtableข้อแตกต่างที่สามของ
HashtablevsHashMapคือHashtableคลาสที่ล้าสมัยและคุณควรใช้ConcurrentHashMapแทนHashtableJava
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แต่ก็ยอมรับคู่ค่าคีย์ จะช่วยให้เป็นโมฆะสำหรับทั้งกุญแจและค่า ประสิทธิภาพการทำงานที่ดีขึ้นจะดีกว่าเพราะมันเป็นHashTableunsynchronized
ตัวอย่าง:
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 ที่ให้ไว้ด้านล่าง