ความแตกต่างระหว่าง HashMap และ Hashtable เหรอ?


3749

อะไรคือความแตกต่างระหว่าง a HashMapและ a Hashtableใน Java?

มีประสิทธิภาพมากขึ้นสำหรับแอปพลิเคชั่นที่ไม่ได้ทำการเธรด?


17
HashTable ล้าสมัยแล้วใน Java 1.7 และแนะนำให้ใช้การใช้งาน ConcurrentMap
MissFiona

@MissFiona ไม่มีConcurrentMapคือไม่จำเป็นที่นี่เป็นคำถามที่ว่า“ใช้งานที่ไม่ใช่เกลียว” ความหมายเกลียว / พร้อมกันคือไม่เป็นปัญหา
Basil Bourque

คำตอบ:


3774

มีความแตกต่างระหว่างHashMapและHashtableใน Java:

  1. Hashtableถูกซิงโครไนซ์ในขณะที่HashMapไม่ใช่ สิ่งนี้จะทำให้HashMapดีขึ้นสำหรับแอปพลิเคชันที่ไม่ได้ใช้เธรดเนื่องจากวัตถุที่ไม่ซิงโครไนซ์มักจะทำงานได้ดีกว่าซิงโครไนซ์

  2. Hashtableไม่อนุญาตให้ใช้nullคีย์หรือค่า HashMapอนุญาตหนึ่งnullคีย์และจำนวนnullค่าใด ๆ

  3. หนึ่งใน subclasses HashMap เป็นLinkedHashMapดังนั้นในกรณีที่คุณต้องการเพื่อย้ำคาดเดาได้ (ซึ่งเป็นคำสั่งแทรกโดยค่าเริ่มต้น), คุณได้อย่างง่ายดายสามารถสลับออกมาหาHashMap นี้จะไม่เป็นเรื่องง่ายถ้าคุณกำลังใช้LinkedHashMapHashtable

HashMapตั้งแต่การประสานไม่เป็นปัญหาสำหรับคุณผมอยากแนะนำให้ หากการซิงโครไนซ์กลายเป็นปัญหาคุณอาจดูConcurrentHashMapด้วย


84
หากคุณต้องการที่จะทำให้ HashMap Collections.synchronizedMap()ด้ายปลอดภัยใช้
Rok Strniša

275
ฉันยังจะแสดงความคิดเห็นว่าวิธีการที่ไร้เดียงสาเพื่อความปลอดภัยของเธรดในHashtable("การซิงโครไนซ์ทุกวิธีควรดูแลปัญหาการเกิดพร้อมกันใด ๆ !") ทำให้แย่ลงมากสำหรับแอปพลิเคชันแบบเธรด คุณจะดีกว่าเมื่อทำการซิงโครไนซ์ภายนอกHashMap(และคิดถึงผลที่ตามมา) หรือใช้ConcurrentMapการนำไปใช้ Bottom line: เหตุผลเดียวที่จะใช้Hashtableคือเมื่อ API ดั้งเดิม (จากแคลิฟอร์เนีย 1996) ต้องการมัน
erickson

8
HashMap ให้ความยืดหยุ่นแก่โปรแกรมเมอร์ในการเขียน threadSafe code เมื่อใช้งานจริง มันเกิดขึ้นน้อยมากที่ฉันต้องการคอลเลกชันที่ปลอดภัยของเธรดเช่น ConcurrentHashMap หรือ HashTable สิ่งที่ฉันต้องการคือชุดของฟังก์ชั่นหรือข้อความบางอย่างในบล็อกที่ซิงโครไนซ์ให้เป็น threadsafe
Gaurava Agarwal

2
Hashtable ล้าสมัยและเราใช้ HashMap สำหรับสภาพแวดล้อมที่ไม่ปลอดภัยสำหรับเธรด หากคุณต้องการความปลอดภัยของเธรดคุณสามารถใช้ Collections.synchronizedMap () หรือใช้ ConcurrentHashMap ซึ่งมีประสิทธิภาพมากกว่านั้น hashtable
Maneesh Kumar

1
มันล้าสมัย แต่ไม่คัดค้านและฉันสงสัยว่าทำไมจึงเป็นเช่นนี้ ฉันเดาว่าการลบคลาสนี้ (และ Vector ด้วยเหตุผลเดียวกัน) จะทำลายรหัสที่มีอยู่มากเกินไปและการเพิ่มความคิดเห็นด้วย @Deprecated จะแสดงถึงเจตนาที่จะลบรหัสซึ่งเห็นได้ชัดว่าไม่ได้อยู่ที่นั่น
Jilles van Gurp

682

โปรดทราบว่าคำตอบจำนวนมากระบุว่า 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);

53
นอกจากนี้โปรดทราบว่าหาก HashMap ถูกปรับเปลี่ยนตัวทำซ้ำที่ชี้ไปจะแสดงผลไม่ถูกต้อง
Chris K

3
ดังนั้นจึงมีความแตกต่างระหว่างทำข้อมูลให้ตรงกัน (myMap) {... } และ ConcurrentHashMap ในแง่ของความปลอดภัยของเธรดหรือไม่
telebog

3
จริงมากฉันพยายามอธิบายเช่นเดียวกันที่นี่ .. lovehasija.com/2012/08/16/…
Love Hasija

@Bushan: มันจะเป็นการพยายามอย่างดีที่สุดซึ่งไม่ได้รับประกันพฤติกรรม: docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Matt Stephenson

การได้อยู่ในช่วงกลางของทีมพัฒนา JVM เป็นเวลาหลายปีที่ฉันสามารถระบุได้ว่าการซิงค์ภายในของ Hashtable มีประโยชน์อย่างน้อยสำหรับการชี้นิ้วที่รหัสลูกค้าอย่างถูกต้องเมื่อเขาเขียนรหัสหลบหลีกพร้อมกัน เราได้รับข้อร้องเรียนหลายประการเกี่ยวกับความล้มเหลวใน HashMap (และด้วยเหตุนี้ "ชัดแจ้ง" ข้อบกพร่อง JDK / JVM) เมื่อสาเหตุนั้นเกิดขึ้นพร้อมกัน
Hot Licks

363

Hashtableถือเป็นรหัสดั้งเดิม ไม่มีอะไรที่เกี่ยวกับเรื่องHashtableที่ไม่สามารถทำได้โดยใช้HashMapหรือดัดแปลงของHashMapดังนั้นสำหรับรหัสใหม่ผมไม่เห็นเหตุผลใด ๆ Hashtableที่จะกลับไป


101
จาก Hashtable javadoc (เน้นการเพิ่ม): "ในฐานะของแพลตฟอร์ม Java 2 แพลตฟอร์ม v1.2, ชั้นนี้ได้รับการดัดแปลงเพื่อใช้ส่วนต่อประสานแผนที่ Map ทำให้เป็นสมาชิกของ Java Collections Framework " อย่างไรก็ตามคุณถูกต้องว่าเป็นรหัสเดิม คุณสามารถรับประโยชน์ทั้งหมดของการซิงโครไนซ์ได้อย่างมีประสิทธิภาพยิ่งขึ้นด้วย Collections.synchronizedMap (HashMap) (คล้ายกับเวกเตอร์ที่เป็นรุ่นดั้งเดิมของ Collections.synchronizedList (ArrayList))
Kip

15
@ aberrant80: น่าเสียดายที่คุณไม่มีทางเลือกระหว่างสองคนนี้และต้องใช้ Hashtable เมื่อเขียนโปรแกรมสำหรับ J2ME ...
pwes

6
คำตอบนี้ควรถูกลบ มันมีข้อมูลที่ไม่ถูกต้องและมี upvotes มากมาย
anon58192932

@ anon58192932 เป็นไปได้หรือไม่ที่จะแก้ไขคำถามเพื่อแก้ไข
GC_

1
เราต้องได้รับความสนใจจากผู้โพสต์ @ aberrant80 หรือผู้ดูแลโดยการตั้งค่าสถานะ การตั้งค่าสถานะสามารถช่วยได้ - จะลองทำตอนนี้
anon58192932

189

คำถามนี้มักถูกถามในการสัมภาษณ์เพื่อตรวจสอบว่าผู้สมัครเข้าใจการใช้ชั้นเรียนที่ถูกต้องหรือไม่และตระหนักถึงทางเลือกอื่น ๆ

  1. HashMapระดับคือประมาณเทียบเท่ากับการHashtableยกเว้นว่ามันไม่ใช่ตรงกันและ nulls ใบอนุญาต ( HashMapอนุญาตให้ค่า Null เป็นคีย์และค่าในขณะที่Hashtableไม่อนุญาตnull)
  2. HashMap ไม่รับประกันว่าลำดับของแผนที่จะคงที่ตลอดเวลา
  3. HashMapไม่ซิงโครไนซ์ในขณะที่Hashtableซิงโครไนซ์
  4. Iterator ใน the HashMapไม่ปลอดภัยในขณะที่ตัวแจงนับสำหรับHashtableis ไม่และโยนConcurrentModificationExceptionหากเธรดอื่นใดแก้ไขแผนที่โครงสร้างโดยการเพิ่มหรือลบองค์ประกอบใด ๆ ยกเว้น วิธีการIteratorของตัวเอง remove()แต่นี่ไม่ใช่พฤติกรรมที่รับประกันและจะทำโดย JVM ในความพยายามอย่างดีที่สุด

หมายเหตุเกี่ยวกับข้อกำหนดที่สำคัญบางประการ:

  1. การซิงโครไนซ์หมายถึงเธรดเดียวเท่านั้นที่สามารถปรับเปลี่ยนตารางแฮชได้ในคราวเดียว โดยทั่วไปหมายความว่าเธรดใด ๆ ก่อนที่จะทำการอัปเดตเกี่ยวกับ a Hashtableจะต้องได้รับการล็อคบนวัตถุในขณะที่คนอื่นจะรอการปลดล็อค
  2. Fail-safe เกี่ยวข้องกับบริบทของตัววนซ้ำ หากมีการสร้างตัววนซ้ำบนวัตถุคอลเลกชันและบางเธรดอื่นพยายามแก้ไขวัตถุคอลเลกชัน "โครงสร้าง" ข้อยกเว้นการปรับเปลี่ยนพร้อมกันจะถูกโยนทิ้ง เป็นไปได้สำหรับเธรดอื่นแม้ว่าจะเรียกใช้setเมธอดเนื่องจากไม่ได้แก้ไขคอลเล็กชัน "โครงสร้าง" อย่างไรก็ตามถ้าก่อนที่จะโทรsetคอลเลกชันที่ได้รับการแก้ไขโครงสร้างIllegalArgumentExceptionจะถูกโยน
  3. การดัดแปลงเชิงโครงสร้างหมายถึงการลบหรือการแทรกองค์ประกอบซึ่งสามารถเปลี่ยนโครงสร้างของแผนที่ได้อย่างมีประสิทธิภาพ

HashMap สามารถทำข้อมูลให้ตรงกันโดย

Map m = Collections.synchronizeMap(hashMap);

แผนที่แสดงมุมมองคอลเล็กชันแทนที่จะสนับสนุนโดยตรงสำหรับการวนซ้ำผ่านวัตถุการแจงนับ มุมมองคอลเลกชันช่วยเพิ่มความรู้สึกของอินเทอร์เฟซอย่างมากดังที่กล่าวไว้ในส่วนนี้ แผนที่ช่วยให้คุณสามารถวนซ้ำคีย์ค่าหรือคู่คีย์ - ค่า Hashtableไม่มีตัวเลือกที่สาม แผนที่เป็นวิธีที่ปลอดภัยในการลบรายการในระหว่างการทำซ้ำ Hashtableไม่ได้. ในที่สุด Map จะแก้ไขข้อบกพร่องเล็กน้อยในHashtableอินเทอร์เฟซ Hashtableมีวิธีการที่เรียกว่า contain ซึ่งจะคืนค่า true ถ้า Hashtableมีค่าที่กำหนด ชื่อของคุณคาดหวังวิธีนี้เพื่อกลับจริงถ้ามีคีย์ที่กำหนดเพราะที่สำคัญคือกลไกการเข้าถึงหลักสำหรับHashtable Hashtableส่วนต่อประสานแผนที่จะกำจัดแหล่งที่มาของความสับสนนี้ด้วยการเปลี่ยนชื่อวิธี containsValue. นอกจากนี้ช่วยเพิ่มความสอดคล้องอินเตอร์เฟซฯ - แนวcontainsValuecontainsKey

ส่วนต่อประสานแผนที่


19
คำตอบนี้มีความจริงที่ไม่ถูกต้องอย่างน้อย 2 ข้อ แน่นอนมันไม่สมควรได้รับ upvotes มากมายนี้
สตีเฟ่นซี

58
1) ตัววนซ้ำของ HashMap ไม่ปลอดภัย พวกเขาจะล้มเหลวอย่างรวดเร็ว มีความหมายแตกต่างกันอย่างมากระหว่างคำสองคำนี้ 2) ไม่มีคือการดำเนินการในset HashMap3) การput(...)ดำเนินการจะไม่โยนIllegalArgumentExceptionหากมีการเปลี่ยนแปลงก่อนหน้านี้ 4) ลักษณะการทำงานที่ล้มเหลวอย่างรวดเร็วของHashMap ยังเกิดขึ้นถ้าคุณเปลี่ยนการแมป 5) พฤติกรรมล้มเหลวอย่างรวดเร็วมีการรับประกัน (สิ่งที่ไม่สามารถรับประกันได้คือพฤติกรรมของ a HashTableหากคุณทำการปรับเปลี่ยนพร้อมกันพฤติกรรมที่แท้จริงคือ ... คาดเดาไม่ได้)
สตีเฟ่นซี

25
6) Hashtableไม่รับประกันว่าลำดับขององค์ประกอบแผนที่จะมีเสถียรภาพตลอดเวลาเช่นกัน (คุณจะอาจจะทำให้เกิดความสับสนHashtableกับLinkedHashMap.)
สตีเฟ่นซี

4
มีใครอีกบ้างที่เป็นกังวลว่านักเรียนในทุกวันนี้ได้รับความคิดที่ผิดพลาดว่าการได้รับ "การซิงโครไนซ์รุ่น" ของคอลเลกชันอย่างใดหมายความว่าคุณไม่จำเป็นต้องซิงโครไนซ์ภายนอก ตัวอย่างโปรดของฉันเกี่ยวกับสิ่งนี้thing.set(thing.get() + 1);ซึ่งบ่อยครั้งมากกว่าที่จะไม่จับมือใหม่ด้วยความประหลาดใจที่ไม่มีการป้องกันอย่างสมบูรณ์โดยเฉพาะอย่างยิ่งถ้าวิธีการget()และset()มีการซิงโครไนซ์ หลายคนคาดว่าจะมีเวทย์มนตร์

Iterators on HashMap ไม่ปลอดภัย
Abdul

130

HashMap: การใช้Mapอินเทอร์เฟซที่ใช้รหัสแฮชเพื่อจัดทำดัชนีอาร์เรย์ Hashtable: สวัสดีปี 1998 เรียกว่า พวกเขาต้องการ API คอลเลกชันของพวกเขากลับมา

อย่างจริงจังแม้ว่าคุณจะดีกว่าอยู่ห่างจากHashtableทั้งหมด สำหรับแอพพลิเคชั่นที่มีเธรดเดียวคุณไม่ต้องการโอเวอร์เฮดของการซิงโครไนซ์เพิ่มเติม สำหรับแอพที่มีความพร้อมสูงการซิงโครไนซ์หวาดระแวงอาจนำไปสู่ความอดอยากการหยุดชะงักหรือการรวบรวมขยะที่ไม่จำเป็นหยุดชั่วคราว คุณอาจใช้ConcurrentHashMapแทนทิมฮาวแลนด์แทน


เรื่องนี้ทำให้รู้สึกจริง ConcurrentHashMaps ให้อิสระในการซิงโครไนซ์และการดีบักได้ง่ายขึ้น
prap19

1
นี่คือเฉพาะกับ Java หรือการใช้งานแผนที่แฮชทั้งหมด

125

โปรดทราบว่าHashTableเป็นคลาสดั้งเดิมก่อนที่จะมีการแนะนำ Java Collections Framework (JCF) และได้รับการดัดแปลงในภายหลังเพื่อปรับใช้Mapอินเตอร์เฟส ดังนั้นเป็นและVectorStack

ดังนั้นให้อยู่ห่างจากพวกเขาในรหัสใหม่เสมอเพราะมีทางเลือกที่ดีกว่าใน JCFเหมือนที่คนอื่น ๆ ชี้ไว้

นี่คือชีทการสะสม Javaที่คุณจะพบว่ามีประโยชน์ สังเกตว่าบล็อกสีเทาประกอบด้วยคลาส HashTable, Vector และ Stack

ป้อนคำอธิบายรูปภาพที่นี่


72

มีคำตอบที่ดีมากมายที่โพสต์แล้ว ฉันกำลังเพิ่มจุดใหม่ไม่กี่แห่งและสรุปมัน

HashMapและHashtableทั้งสองจะถูกนำมาใช้ในการจัดเก็บข้อมูลในรูปแบบที่สำคัญและความคุ้มค่า ทั้งสองกำลังใช้เทคนิคการแปลงแป้นพิมพ์เพื่อจัดเก็บคีย์ที่ไม่ซ้ำกัน แต่มีความแตกต่างมากมายระหว่างคลาส HashMap และ Hashtable ที่ให้ไว้ด้านล่าง

HashMap

  1. HashMapไม่ตรง ไม่ปลอดภัยสำหรับเธรดและไม่สามารถแชร์ระหว่างหลายเธรดได้หากไม่มีรหัสการซิงโครไนซ์ที่เหมาะสม
  2. HashMap อนุญาตหนึ่งคีย์ null และหลายค่า null
  3. HashMap เป็นคลาสใหม่ที่เปิดตัวใน JDK 1.2
  4. HashMap รวดเร็ว
  5. เราสามารถทำการHashMapซิงโครไนซ์โดยเรียกรหัสนี้
    Map m = Collections.synchronizedMap(HashMap);
  6. HashMap ถูก traversed โดย Iterator
  7. การวนซ้ำในHashMapนั้นล้มเหลวอย่างรวดเร็ว
  8. HashMap สืบทอดคลาส AbstractMap

Hashtable

  1. Hashtableถูกทำข้อมูลให้ตรงกัน มันปลอดภัยสำหรับเธรดและสามารถแชร์กับหลายเธรดได้
  2. Hashtable ไม่อนุญาตคีย์หรือค่า Null ใด ๆ
  3. Hashtable เป็นคลาสดั้งเดิม
  4. Hashtable ช้า
  5. Hashtable ถูกซิงโครไนซ์ภายในและไม่สามารถซิงโครไนซ์ได้
  6. Hashtable ถูก traversed โดย Enumerator และ Iterator
  7. ตัวแจงนับในHashtableไม่ใช่แบบล้มเหลว
  8. Hashtable สืบทอดคลาสพจนานุกรม

อ่านเพิ่มเติมความแตกต่างระหว่าง HashMap และ Hashtable ใน Java คืออะไร?

ป้อนคำอธิบายรูปภาพที่นี่


พริตตี้ปกคลุมมากในคำตอบนี้ (dupicate ของ) - stackoverflow.com/a/39785829/432903
prayagupd

ทำไมคุณถึงพูดว่า ~ " Hashtable เป็นคลาสดั้งเดิม "? เอกสารสนับสนุนอยู่ที่ไหน
IgorGanapolsky

2
@IgorGanapolsky คุณสามารถอ่านได้ - stackoverflow.com/questions/21086307/…
roottraveller

การดูแล HashMap นั้นแพงกว่า TreeMap เนื่องจาก HashMap สร้างที่เก็บข้อมูลเพิ่มเติมที่ไม่จำเป็น
Abdul

64

นอกจากสิ่งที่ izb กล่าวแล้วยังHashMapอนุญาตให้มีค่า Null ในขณะที่Hashtableไม่รองรับ

โปรดทราบด้วยว่าการHashtableขยายDictionaryคลาสซึ่งเป็นสถานะJavadocsนั้นล้าสมัยและถูกแทนที่ด้วยMapอินเตอร์เฟส


3
แต่นั่นไม่ได้ทำให้ HashTable ล้าสมัยใช่ไหม?
Pacerier

@Pacerier HashTable ล้าสมัยแล้วตั้งแต่ Java 1.7
Majid Ali Khan

62

ลองดูที่แผนภูมินี้ มันมีการเปรียบเทียบระหว่างโครงสร้างข้อมูลที่แตกต่างกันพร้อมกับและHashMap Hashtableการเปรียบเทียบมีความแม่นยำชัดเจนและเข้าใจง่าย

Java Collection Matrix


49

Hashtableคล้ายกับHashMapและมีส่วนต่อประสานที่คล้ายกัน ขอแนะนำให้คุณใช้HashMapเว้นแต่คุณจะต้องการการสนับสนุนสำหรับแอปพลิเคชันรุ่นเก่าหรือคุณต้องการการซิงโครไนซ์เนื่องจากHashtablesวิธีการซิงโครไนซ์ ดังนั้นในกรณีของคุณเนื่องจากคุณไม่ได้ใช้มัลติเธรดHashMapsเป็นทางออกที่ดีที่สุดของคุณ


36

ข้อแตกต่างที่สำคัญอีกอย่างหนึ่งระหว่าง hashtable และ hashmap คือ Iterator ใน HashMap นั้นล้มเหลวอย่างรวดเร็วในขณะที่ตัวแจงนับสำหรับ Hashtable ไม่ได้และโยน ConcurrentModificationException หากเธรดอื่นใดแก้ไขแผนที่โครงสร้างโดยการเพิ่มหรือลบองค์ประกอบใด ๆ แต่นี่ไม่ใช่พฤติกรรมที่รับประกันและจะทำโดย JVM ในความพยายามอย่างดีที่สุด "

แหล่งที่มาของฉัน: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html


36

นอกเหนือจากส่วนที่สำคัญอื่น ๆ ที่กล่าวถึงแล้วที่นี่ 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 หรือไม่?


34

Hashtableทำข้อมูลให้ตรงกันในขณะที่HashMapไม่ ที่ทำให้ช้ากว่าHashtableHashmap

สำหรับแอพที่ไม่ใช่เธรดให้ใช้HashMapเนื่องจากเป็นแอปที่ทำงานเหมือนกัน


30
  • 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 ฉันเดาว่าเหมือนกัน แต่ฉันไม่แน่ใจทั้งหมดฉันไม่พบแหล่งที่มาที่ระบุชัดเจน


30

HashMapและHashtableมีความแตกต่างของอัลกอริทึมที่สำคัญเช่นกัน ไม่มีใครพูดถึงเรื่องนี้มาก่อนนั่นคือสาเหตุที่ฉันนำมันมาใช้ HashMapจะสร้างตารางแฮชที่มีกำลังสองขนาดเพิ่มขึ้นแบบไดนามิกเพื่อให้คุณมีองค์ประกอบได้มากถึงแปดองค์ประกอบ (การชนกัน) ในที่ฝากข้อมูลใด ๆ และจะกระตุ้นองค์ประกอบให้ดีสำหรับประเภทองค์ประกอบทั่วไป อย่างไรก็ตามการHashtableใช้งานนั้นให้การควบคุม hashing ที่ดีกว่าและดีกว่าถ้าคุณรู้ว่าคุณกำลังทำอะไรอยู่นั่นคือคุณสามารถแก้ไขขนาดของตารางโดยใช้หมายเลขที่ใกล้เคียงที่สุดกับขนาดโดเมนของคุณซึ่งจะทำให้ประสิทธิภาพดีกว่า HashMap สำหรับบางกรณี

แยกจากความแตกต่างที่ชัดเจนที่กล่าวถึงอย่างกว้างขวางในคำถามนี้ฉันเห็น Hashtable เป็นรถ "ไดรฟ์แบบแมนนวล" ที่คุณสามารถควบคุมการแฮชและ HashMap ได้ดีกว่าในฐานะ "ไดรฟ์อัตโนมัติ" ที่ทำงานได้ดี


27

จากข้อมูลที่นี่ฉันขอแนะนำให้ไปกับ HashMap ฉันคิดว่าข้อได้เปรียบที่ใหญ่ที่สุดคือ Java จะป้องกันไม่ให้คุณแก้ไขมันในขณะที่คุณกำลังวนซ้ำมันจนกว่าคุณจะทำมันผ่านตัววนซ้ำ


5
มันไม่ได้ป้องกันมันจริง ๆ เพียงแค่ตรวจจับและโยนข้อผิดพลาด
Bart van Heukelom

1
ฉันค่อนข้างแน่ใจว่ามันจะมี ConncurrentModificationException ก่อนที่จะมีการแก้ไขคอลเล็กชันพื้นฐานแม้ว่าฉันอาจจะผิด
pkaeding

มันจะพยายามตรวจหาการแก้ไขพร้อมกันและส่งข้อยกเว้น แต่ถ้าคุณทำอะไรกับเธรดมันก็ไม่สามารถรับประกันได้ แน่นอนสิ่งที่สามารถเกิดขึ้นรวมทั้งความแตกแยก
cHao

24

เอ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)

Hash Map & Hashtable

« การดัดแปลงโครงสร้างในกรณีที่มีการชนกันของแฮช

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


@ดู



17

1. HashmapและHashTableเก็บรหัสและค่า

2. สามารถเก็บหนึ่งที่สำคัญเป็นHashmap ไม่สามารถเก็บnullHashtablenull

3. HashMapไม่ได้ซิงโครไนซ์ แต่Hashtableซิงโครไนซ์

4. HashMapสามารถทำข้อมูลให้ตรงกันกับCollection.SyncronizedMap(map)

Map hashmap = new HashMap();

Map map = Collections.SyncronizedMap(hashmap);

16

นอกเหนือจากความแตกต่างที่กล่าวมาแล้วก็ควรจะตั้งข้อสังเกตว่าตั้งแต่ Java 8 HashMapแบบไดนามิกแทนที่โหนด (รายการที่เชื่อมโยง) ที่ใช้ในแต่ละถังมี TreeNodes (ต้นไม้แดงดำ) ดังนั้นแม้ว่าชนกัญชาสูงอยู่กรณีที่เลวร้ายที่สุดเมื่อ การค้นหาคือ

O (เข้าสู่ระบบ (n)) สำหรับHashMap Vs O (n) Hashtableใน

* การปรับปรุงดังกล่าวยังไม่ได้ถูกนำไปใช้Hashtableแต่เพียงเพื่อHashMap, และLinkedHashMapConcurrentHashMap

FYI ปัจจุบัน

  • TREEIFY_THRESHOLD = 8 : ถ้าที่เก็บข้อมูลมีมากกว่า 8 โหนดรายการที่เชื่อมโยงจะถูกเปลี่ยนเป็นโครงสร้างที่สมดุล
  • UNTREEIFY_THRESHOLD = 6 : เมื่อที่เก็บข้อมูลมีขนาดเล็กเกินไป (เนื่องจากการลบหรือปรับขนาด) ต้นไม้จะถูกแปลงกลับไปเป็นรายการที่เชื่อมโยง

14

มีความแตกต่างพื้นฐาน 5 ประการด้วย HashTable และ HashMaps

  1. แผนที่ช่วยให้คุณสามารถวนซ้ำและเรียกคืนคีย์ค่าและคู่คีย์ - ค่าได้เช่นกันโดยที่ HashTable ไม่มีความสามารถทั้งหมดนี้
  2. ใน Hashtable มีฟังก์ชั่นประกอบด้วย () ซึ่งทำให้เกิดความสับสนในการใช้งาน เพราะความหมายของการบรรจุนั้นเบี่ยงเบนไปเล็กน้อย หมายความว่ามีรหัสหรือมีค่าหรือไม่ ยากที่จะเข้าใจ สิ่งเดียวกันในแผนที่เรามีฟังก์ชั่น containKey () และ containValue () ซึ่งง่ายต่อการเข้าใจ
  3. ใน hashmap คุณสามารถลบองค์ประกอบในขณะที่วนซ้ำได้อย่างปลอดภัย ในกรณีที่ไม่สามารถทำได้ในแฮชเทเบิล
  4. HashTables เป็นการซิงโครไนซ์เริ่มต้นดังนั้นจึงสามารถใช้กับหลายเธรดได้อย่างง่ายดาย โดยที่ HashMaps ไม่ถูกซิงโครไนซ์โดยค่าเริ่มต้นดังนั้นสามารถใช้กับเธรดเดียวเท่านั้น แต่คุณยังสามารถแปลง HashMap เป็นซิงโครไนซ์ได้โดยใช้ฟังก์ชั่น synchronMap (Map m) ของ Collections util class
  5. HashTable จะไม่อนุญาตให้ใช้คีย์ว่างหรือค่า Null โดยที่ HashMap อนุญาตให้ใช้หนึ่งคีย์ที่เป็นโมฆะและค่า Null หลายค่า

13

ผลงานเล็ก ๆ ของฉัน:

  1. สิ่งแรกและสำคัญที่สุดที่แตกต่างระหว่างHashtableและHashMapคือHashMapไม่ปลอดภัยในขณะที่Hashtableเป็นคอลเลกชันของเธรดที่ปลอดภัย

  2. แตกต่างที่สำคัญระหว่างสองHashtableและHashMapเป็นผลการดำเนินงานตั้งแต่จะไม่ตรงกันมันทำงานได้ดีกว่าHashMapHashtable

  3. ข้อแตกต่างที่สามของHashtablevs HashMapคือHashtableคลาสที่ล้าสมัยและคุณควรใช้ConcurrentHashMapแทนHashtableJava


11

HashMap: เป็นคลาสที่มีอยู่ในแพ็คเกจ java.util และใช้เพื่อจัดเก็บองค์ประกอบในรูปแบบคีย์และค่า

Hashtable: เป็นคลาสดั้งเดิมที่ได้รับการยอมรับในกรอบการรวบรวม


หากเป็นเช่นนั้นควรอยู่ในความคิดเห็นที่ไม่เป็นคำตอบ
manikant gautam

10

HashTableเป็นคลาสดั้งเดิมใน jdk ที่ไม่ควรใช้อีกต่อไป แทนที่การใช้งานของมันด้วยConcurrentHashMap หากคุณไม่ต้องการความปลอดภัยของเธรดให้ใช้HashMapซึ่งไม่ใช่threadsafeแต่เร็วกว่าและใช้หน่วยความจำน้อยกว่า


เพราะฉันคิดว่าคำตอบอื่น ๆ ในเวลานั้นไม่ได้ละทิ้ง HashTable แต่อธิบายว่ามันเป็น threadsafe ความจริงก็คือทันทีที่คุณเห็น HashTable ในโค้ดคุณควรแทนที่ด้วย ConcurrentHashMap โดยไม่ข้ามจังหวะ และหากความปลอดภัยของเธรดไม่ได้เป็นข้อกังวล HashMap สามารถใช้ปรับปรุงประสิทธิภาพได้เล็กน้อย
jontejj

10
  1. Hashtableทำข้อมูลให้ตรงกันในขณะที่HashMapไม่
  2. ความแตกต่างก็คือว่า iterator ในHashMapคือไม่ปลอดภัยในขณะที่การแจงนับสำหรับการHashtableไม่ได้ หากคุณเปลี่ยนแผนที่ในขณะที่วนซ้ำคุณจะรู้
  3. HashMapอนุญาตให้มีค่า Null ในขณะที่Hashtableไม่

3
ตัววนซ้ำ HashMap ล้มเหลวเร็วไม่ปลอดภัย นั่นคือเหตุผลที่เรามี ConcurrentHashMap ที่อนุญาตให้ทำการปรับเปลี่ยนในขณะทำซ้ำ ตรวจสอบโพสต์นี้journaldev.com/122/…
Pankaj

9

HashMap และ HashTable

  • บางจุดที่สำคัญเกี่ยวกับ HashMap และ HashTable โปรดอ่านรายละเอียดด้านล่าง

1) Hashtable และ Hashmap ใช้ส่วนต่อประสาน java.util.Map 2) ทั้ง Hashmap และ Hashtable เป็นชุดที่ใช้แฮช และทำงานเกี่ยวกับการคร่ำครวญ ดังนั้นสิ่งเหล่านี้จึงมีความคล้ายคลึงกันของ HashMap และ HashTable

  • ความแตกต่างระหว่าง HashMap และ HashTable คืออะไร

1) ความแตกต่างแรกคือ HashMap ไม่ปลอดภัยในขณะที่ด้าย HashTable เป็น ThreadSafe
2) HashMap มีประสิทธิภาพดีกว่าเพราะมันไม่ปลอดภัย ในขณะที่ประสิทธิภาพการทำงานของ Hashtable ที่ชาญฉลาดนั้นไม่ได้ดีกว่าเพราะมันปลอดภัยสำหรับเธรด ดังนั้นหลายเธรดไม่สามารถเข้าถึง Hashtable ได้ในเวลาเดียวกัน


2
ลงคะแนนเนื่องจากคำตอบนี้ไม่ถูกต้องในบางด้าน Hashtable ไม่ได้ใช้อินเทอร์เฟซแผนที่ แต่ขยายคลาส Dictionary เท่านั้นซึ่งล้าสมัย
Yannis Sermetziadis

8

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));

    }
}

5

HashMapถูกจำลองและใช้งานได้ในGWT client codeขณะที่Hashtableไม่ใช่


นั่นเป็นคำอธิบายที่ครอบคลุมเกี่ยวกับความแตกต่างระหว่างสอง apis หรือไม่?
IgorGanapolsky

ใช่ (sic!) นั่นคือทั้งหมดที่นักพัฒนา GWT จำเป็นต้องรู้
pong

5

หัวข้อเก่าและคลาสสิกเพียงต้องการเพิ่มบล็อกที่มีประโยชน์นี้ซึ่งอธิบายสิ่งนี้:

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

  1. หนึ่งในความแตกต่างที่สำคัญระหว่าง HashMap และ Hashtable คือ HashMap นั้นไม่ได้ทำการซิงโครไนซ์ในขณะที่ Hashtable ถูกซิงโครไนซ์ซึ่งหมายความว่า Hashtable นั้นปลอดภัยสำหรับเธรดและสามารถแชร์ระหว่างหลายเธรดได้ แต่ HashMap Java 5 แนะนำ ConcurrentHashMap ซึ่งเป็นทางเลือกของ Hashtable และให้ความสามารถในการขยายที่ดีกว่า Hashtable ใน Java.Synchronized หมายความว่ามีเพียงเธรดเดียวเท่านั้นที่สามารถแก้ไขตารางแฮชได้ ณ จุดเดียว โดยทั่วไปหมายความว่าเธรดใด ๆ ก่อนที่จะทำการอัปเดตบน hashtable จะต้องได้รับการล็อกบนวัตถุในขณะที่คนอื่นจะรอการปลดล็อค

  2. คลาส HashMap นั้นเทียบเท่ากับ Hashtable ยกเว้นว่าอนุญาตให้เป็นโมฆะ (HashMap อนุญาตให้มีค่า Null เป็นคีย์และค่าในขณะที่ Hashtable ไม่อนุญาตให้มีค่า Null)

  3. ความแตกต่างที่สำคัญที่สามระหว่าง HashMap กับ Hashtable คือ Iterator ใน HashMap นั้นเป็นตัววนซ้ำที่ล้มเหลวอย่างรวดเร็วในขณะที่ตัวแจงนับสำหรับ Hashtable ไม่ได้และโยน ConcurrentModificationException หากเธรดอื่นใดแก้ไขแผนผังโครงสร้างโดยลบหรือลบองค์ประกอบใด ๆ ) วิธี. แต่นี่ไม่ใช่พฤติกรรมที่รับประกันและจะทำโดย JVM ในความพยายามอย่างดีที่สุด นี่คือความแตกต่างที่สำคัญระหว่างการแจงนับและ Iterator ใน Java

  4. ความแตกต่างที่น่าสังเกตอีกอย่างหนึ่งระหว่าง Hashtable และ HashMap คือเนื่องจากความปลอดภัยของเธรดและการซิงโครไนซ์ Hashtable นั้นช้ากว่า HashMap มากหากใช้ในสภาพแวดล้อมเธรดเดี่ยว ดังนั้นหากคุณไม่ต้องการการซิงโครไนซ์และ HashMap จะใช้งานโดยเธรดเดียวเท่านั้นจึงจะใช้งาน Hashtable ใน Java ได้

  5. HashMap ไม่รับประกันว่าคำสั่งของแผนที่จะคงที่ตลอดเวลา

โปรดทราบว่า HashMap สามารถซิงโครไนซ์ได้

Map m = Collections.synchronizedMap(hashMap);

โดยสรุปมีความแตกต่างที่สำคัญระหว่าง Hashtable และ HashMap ใน Java เช่นความปลอดภัยของเธรดและความเร็วและจากนั้นใช้ Hashtable เฉพาะเมื่อคุณต้องการความปลอดภัยของเธรดอย่างแน่นอนหากคุณใช้ Java 5 ให้พิจารณาใช้ ConcurrentHashMap ใน Java


ConcurrentHashMap ไม่ได้อ่านให้ตรงกันในขณะที่ Hashtable คือ ดังนั้นหากคุณมีการดำเนินการอ่านจำนวนมากที่เกิดขึ้นพร้อมกันกับการเขียน Hashtable จะให้บริการคุณได้ดีขึ้นถ้าคุณใส่ใจกับความถูกต้องของข้อมูล
IgorGanapolsky

5

HashMapและHashtableทั้งคู่ใช้เพื่อเก็บข้อมูลในรูปแบบของคีย์และค่า ทั้งสองกำลังใช้เทคนิคการแปลงแป้นพิมพ์เพื่อจัดเก็บคีย์ที่ไม่ซ้ำกัน มีความแตกต่างมากมายระหว่างคลาส HashMap และ Hashtable ที่ให้ไว้ด้านล่าง

ป้อนคำอธิบายรูปภาพที่นี่


สรุปภาพที่ดี!
Nadjib Mami
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.