Perbedaan antara HashMap dan Hashtable?

3751

Apa perbedaan antara a HashMapdan a Hashtabledi Jawa?

Mana yang lebih efisien untuk aplikasi non-utas?

dmanxiii
sumber
17
HashTable sudah usang di Jawa 1.7 dan disarankan untuk menggunakan implementasi ConcurrentMap
MissFiona
@MissFiona Tidak, ConcurrentMapini tidak diperlukan di sini, sebagai Pertanyaan mengatakan “aplikasi non-threaded” yang berarti threading / konkurensi tidak menjadi masalah.
Basil Bourque

Jawaban:

3775

Ada beberapa perbedaan antara HashMapdan Hashtabledi Jawa:

  1. Hashtableadalah disinkronkan , sedangkan HashMaptidak. Ini membuat HashMaplebih baik untuk aplikasi yang tidak berulir, karena Objek yang tidak disinkronkan biasanya berkinerja lebih baik daripada yang disinkronkan.

  2. Hashtabletidak mengizinkan nullkunci atau nilai. HashMapmemungkinkan satu nullkunci dan sejumlah nullnilai.

  3. Salah satu subclass HashMap adalah LinkedHashMap, jadi jika Anda menginginkan urutan iterasi yang dapat diprediksi (yang merupakan urutan penyisipan secara default), Anda dapat dengan mudah menukar HashMapuntuk a LinkedHashMap. Ini tidak akan semudah jika Anda menggunakan Hashtable.

Karena sinkronisasi bukan masalah bagi Anda, saya sarankan HashMap. Jika sinkronisasi menjadi masalah, Anda juga dapat melihatnya ConcurrentHashMap.

Josh Brown
sumber
84
Jika Anda ingin membuat thread HashMap aman, gunakan Collections.synchronizedMap().
Rok Strniša
275
Saya juga akan berkomentar bahwa pendekatan naif terhadap keamanan utas di Hashtable("menyinkronkan setiap metode harus menangani masalah konkurensi!") Membuatnya jauh lebih buruk untuk aplikasi berulir. Anda lebih baik menyinkronkan secara eksternal HashMap(dan memikirkan konsekuensinya), atau menggunakan ConcurrentMapimplementasi (dan mengeksploitasi API diperpanjang untuk konkurensi). Intinya: satu-satunya alasan untuk menggunakannya Hashtableadalah ketika API lawas (mulai tahun 1996) mengharuskannya.
erickson
8
HashMap memberikan fleksibilitas kepada programmer untuk menulis kode threadSafe ketika mereka benar-benar menggunakannya. Jarang terjadi bahwa saya membutuhkan koleksi thread yang aman seperti ConcurrentHashMap atau HashTable. Apa yang saya butuhkan adalah serangkaian fungsi atau pernyataan tertentu dalam blok yang disinkronkan untuk menjadi threadsafe.
Gaurava Agarwal
2
Hashtable sudah usang dan kami menggunakan HashMap untuk lingkungan yang tidak aman. Jika Anda membutuhkan keamanan utas maka Anda dapat menggunakan Collections.synchronizedMap () atau menggunakan ConcurrentHashMap yang lebih efisien yang memiliki hashtable.
Maneesh Kumar
1
Itu sudah usang tetapi tidak usang dan saya bertanya-tanya mengapa ini terjadi. Saya menduga menghapus kelas ini (dan Vektor untuk alasan yang sama) akan memecah terlalu banyak kode yang ada dan penjelasan dengan @Deprecated akan menyiratkan niat untuk menghapus kode, yang ternyata tidak ada.
Jilles van Gurp
682

Perhatikan, bahwa banyak jawaban menyatakan bahwa Hashtable disinkronkan. Dalam praktiknya ini sangat sedikit membeli Anda. Sinkronisasi yang ada pada metode accessor / mutator akan menghentikan dua utas menambahkan atau menghapus dari peta secara bersamaan, tetapi di dunia nyata Anda akan sering membutuhkan sinkronisasi tambahan.

Idiom yang sangat umum adalah "centang lalu taruh" - yaitu mencari entri di Map, dan menambahkannya jika belum ada. Ini sama sekali bukan operasi atom apakah Anda menggunakan Hashtableatau HashMap.

Sinkronisasi yang setara HashMapdapat diperoleh dengan:

Collections.synchronizedMap(myMap);

Tetapi untuk mengimplementasikan logika ini dengan benar, Anda perlu sinkronisasi tambahan dari formulir:

synchronized(myMap) {
    if (!myMap.containsKey("tomato"))
        myMap.put("tomato", "red");
}

Sekalipun mengulangi Hashtableentri seseorang (atau yang HashMapdiperoleh oleh Collections.synchronizedMap) bukanlah utas aman kecuali Anda juga menjaga agar Maptidak dimodifikasi melalui sinkronisasi tambahan.

Implementasi ConcurrentMapantarmuka (misalnya ConcurrentHashMap) menyelesaikan sebagian dari ini dengan memasukkan semantik periksa-lalu-bertindak semantik seperti:

ConcurrentMap.putIfAbsent(key, value);
serg10
sumber
53
Perhatikan juga bahwa jika HashMap diubah, iterator yang menunjuk padanya tidak valid.
Chris K
3
Jadi apakah ada perbedaan antara disinkronkan (myMap) {...} dan ConcurrentHashMap dalam hal thread aman?
telebog
3
Sangat benar, saya mencoba menjelaskan hal yang sama di sini .. lovehasija.com/2012/08/16/…
Love Hasija
@Bhushan: Ini akan memberikan upaya terbaik, ini bukan perilaku yang dijamin: docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Matt Stephenson
Setelah berada di tengah-tengah kru pengembangan JVM selama beberapa tahun saya dapat menyatakan bahwa sinkronisasi internal Hashtable setidaknya berguna untuk dengan tepat menunjuk jari pada kode pelanggan ketika ia menulis kode bersamaan yang cerdik. Kami menerima beberapa keluhan tentang kegagalan di dalam HashMap (dan karenanya "jelas" merupakan bug JDK / JVM), ketika penyebabnya adalah modifikasi bersamaan.
Hot Licks
363

Hashtabledianggap sebagai kode warisan. Tidak ada Hashtableyang tidak dapat dilakukan dengan menggunakan HashMapatau derivasi dari HashMap, jadi untuk kode baru, saya tidak melihat ada pembenaran untuk kembali ke Hashtable.

aberrant80
sumber
101
Dari Hashtable javadoc (penekanan ditambahkan): "Pada platform Java 2 v1.2, kelas ini dipasang untuk mengimplementasikan antarmuka Peta, menjadikannya anggota Java Collections Framework ." Namun, Anda benar bahwa itu adalah kode lama. Semua manfaat sinkronisasi dapat diperoleh dengan lebih efisien dengan Collections.synchronizedMap (HashMap). (Mirip dengan Vektor menjadi versi warisan dari Collections.synchronizedList (ArrayList).)
Kip
15
@ aberrant80: sayangnya Anda tidak punya pilihan antara keduanya dan harus menggunakan Hashtable ketika pemrograman untuk J2ME ...
pwes
6
jawaban ini harus dihapus. ini berisi informasi yang salah dan memiliki banyak upvotes.
anon58192932
@ anon58192932 Apakah mungkin untuk mengedit pertanyaan untuk memperbaikinya?
GC_
1
Kita harus mendapatkan perhatian dari poster @ aberrant80 atau admin dengan menandai. Pemberian tanda dapat membantu - akan mencobanya sekarang.
anon58192932
189

Pertanyaan ini sering ditanyakan dalam wawancara untuk memeriksa apakah kandidat memahami penggunaan kelas koleksi yang benar dan mengetahui solusi alternatif yang tersedia.

  1. The HashMapkelas kira-kira setara dengan Hashtable, kecuali bahwa itu non disinkronkan dan izin nulls. ( HashMapmemungkinkan nilai nol sebagai kunci dan nilai sedangkan Hashtabletidak mengizinkan nulls).
  2. HashMap tidak menjamin bahwa urutan peta akan tetap konstan seiring waktu.
  3. HashMaptidak disinkronkan sedangkan Hashtabledisinkronkan.
  4. Iterator dalam HashMapgagal-aman sementara enumerator untuk Hashtabletidak dan membuang ConcurrentModificationExceptionjika ada Thread lain memodifikasi peta secara struktural dengan menambahkan atau menghapus elemen apa pun kecuali metode Iteratorsendiri remove(). Tapi ini bukan perilaku yang dijamin dan akan dilakukan oleh JVM pada upaya terbaik.

Catatan tentang Beberapa Ketentuan Penting:

  1. Disinkronkan berarti hanya satu utas yang dapat memodifikasi tabel hash pada satu titik waktu. Pada dasarnya, ini berarti bahwa utas apa pun sebelum melakukan pembaruan pada suatu Hashtableharus mendapatkan kunci pada objek sementara yang lain akan menunggu kunci akan dirilis.
  2. Aman-gagal relevan dalam konteks iterator. Jika iterator telah dibuat pada objek koleksi dan beberapa utas lainnya mencoba mengubah objek koleksi "secara struktural", pengecualian modifikasi bersamaan akan dilempar. Dimungkinkan untuk utas lain meskipun untuk memanggil setmetode karena tidak mengubah koleksi "secara struktural". Namun, jika sebelum menelepon set, koleksi tersebut telah dimodifikasi secara struktural, IllegalArgumentExceptionakan dibuang.
  3. Modifikasi struktural berarti menghapus atau memasukkan elemen yang secara efektif dapat mengubah struktur peta.

HashMap dapat disinkronkan oleh

Map m = Collections.synchronizeMap(hashMap);

Peta menyediakan tampilan Koleksi alih-alih dukungan langsung untuk iterasi melalui objek Enumerasi. Tampilan koleksi sangat meningkatkan ekspresifitas antarmuka, seperti yang akan dibahas nanti di bagian ini. Peta memungkinkan Anda untuk mengulangi kunci, nilai, atau pasangan nilai kunci; Hashtabletidak menyediakan opsi ketiga. Peta menyediakan cara yang aman untuk menghapus entri di tengah iterasi; Hashtabletidak. Akhirnya, Map memperbaiki kekurangan kecil di Hashtableantarmuka. Hashtablememiliki metode yang disebut berisi, yang mengembalikan true jika Hashtableberisi nilai yang diberikan. Diberi nama, Anda akan mengharapkan metode ini mengembalikan true jika Hashtableberisi kunci yang diberikan, karena kuncinya adalah mekanisme akses utama untuk a Hashtable. Antarmuka Peta menghilangkan sumber kebingungan ini dengan mengganti nama metode containsValue. Juga, ini meningkatkan konsistensi antarmuka - containsValueparalel containsKey.

Antarmuka Peta

sravan
sumber
19
Jawaban ini mengandung setidaknya 2 ketidakakuratan faktual yang signifikan. Tentu TIDAK TIDAK layak banyak upvotes ini.
Stephen C
58
1) Iterator HashMap TIDAK gagal-aman. Mereka gagal-cepat. Ada perbedaan besar dalam arti antara kedua istilah itu. 2) Tidak ada setoperasi pada a HashMap. 3) put(...)Operasi tidak akan melempar IllegalArgumentExceptionjika ada perubahan sebelumnya. 4) Perilaku gagal cepat HashMap juga terjadi jika Anda mengubah pemetaan. 5) Perilaku gagal-cepat yang dijamin. (Apa yang tidak dijamin adalah perilaku a HashTablejika Anda melakukan modifikasi bersamaan. Perilaku sebenarnya adalah ... tidak dapat diprediksi.)
Stephen C
25
6) Hashtabletidak menjamin bahwa urutan elemen peta akan stabil dari waktu ke waktu. (Anda mungkin membingungkan Hashtabledengan LinkedHashMap.)
Stephen C
4
Adakah orang lain yang benar-benar khawatir bahwa siswa akhir-akhir ini mendapatkan gagasan yang keliru bahwa mendapatkan "versi yang disinkronkan" dari koleksi entah bagaimana berarti Anda tidak perlu mensinkronisasi secara eksternal operasi gabungan? Contoh favorit saya tentang makhluk ini thing.set(thing.get() + 1);yang lebih sering mengejutkan pemula adalah benar-benar tidak terlindungi, terutama jika get()dan set()merupakan metode yang disinkronkan. Banyak dari mereka mengharapkan sihir.
Iterator di HashMap tidak aman-aman
Abdul
130

HashMap: Implementasi Mapantarmuka yang menggunakan kode hash untuk mengindeks array. Hashtable: Hai, 1998 disebut. Mereka ingin API koleksi mereka kembali.

Namun serius, Anda lebih baik menjauh dari Hashtablesemuanya. Untuk aplikasi single-threaded, Anda tidak perlu overhead sinkronisasi tambahan. Untuk aplikasi yang sangat konkuren, sinkronisasi paranoid dapat menyebabkan kelaparan, kebuntuan, atau pengumpulan sampah yang tidak perlu dihentikan. Seperti yang ditunjukkan Tim Howland, Anda dapat menggunakannya ConcurrentHashMap.

Apocalisp
sumber
Ini sebenarnya masuk akal. ConcurrentHashMaps memberi Anda kebebasan sinkronisasi dan debugging jauh lebih mudah.
prap19
1
Apakah ini khusus untuk Java atau semua implementasi peta hash.
125

Perlu diingat bahwa HashTableitu adalah kelas warisan sebelum Java Collections Framework (JCF) diperkenalkan dan kemudian dipasang kembali untuk mengimplementasikanMap antarmuka. Begitu juga Vectordan Stack.

Oleh karena itu, selalu menjauh dari mereka dalam kode baru karena selalu ada alternatif yang lebih baik di JCF seperti yang ditunjukkan orang lain.

Berikut adalah lembar contekan koleksi Java yang menurut Anda berguna. Perhatikan blok abu-abu berisi kelas warisan HashTable, Vector dan Stack.

masukkan deskripsi gambar di sini

pierrotlefou
sumber
72

Ada banyak jawaban bagus yang sudah diposting. Saya menambahkan beberapa poin baru dan merangkumnya.

HashMapdan Hashtablekeduanya digunakan untuk menyimpan data dalam bentuk kunci dan nilai . Keduanya menggunakan teknik hashing untuk menyimpan kunci unik. Tetapi ada banyak perbedaan antara kelas HashMap dan Hashtable yang diberikan di bawah ini.

HashMap

  1. HashMaptidak disinkronkan. Ini bukan utas aman dan tidak dapat dibagikan di antara banyak utas tanpa kode sinkronisasi yang tepat.
  2. HashMap memungkinkan satu kunci nol dan beberapa nilai nol.
  3. HashMap adalah kelas baru yang diperkenalkan di JDK 1.2.
  4. HashMap cepat.
  5. Kita dapat menjadikannya HashMapdisinkronkan dengan memanggil kode ini
    Map m = Collections.synchronizedMap(HashMap);
  6. HashMap dilalui oleh Iterator.
  7. Iterator dalam HashMapadalah gagal-cepat.
  8. HashMap mewarisi kelas AbstractMap.

Hashtable

  1. Hashtabledisinkronkan. Ini aman untuk thread dan dapat dibagikan dengan banyak utas.
  2. Hashtable tidak mengizinkan kunci atau nilai nol.
  3. Hashtable adalah kelas warisan.
  4. Hashtable lambat.
  5. Hashtable disinkronkan secara internal dan tidak dapat disinkronkan.
  6. Hashtable dilalui oleh Enumerator dan Iterator.
  7. Enumerator dalam Hashtable tidak gagal-cepat.
  8. Hashtable mewarisi kelas Kamus.

Bacaan lebih lanjut Apa perbedaan antara HashMap dan Hashtable di Java?

masukkan deskripsi gambar di sini

roottraveller
sumber
Cukup banyak dibahas dalam jawaban ini (duplikat) - stackoverflow.com/a/39785829/432903 .
prayagupd
Mengapa Anda mengatakan ~ " Hashtable is a legacy class "? Di mana dokumentasi pendukung untuk itu.
IgorGanapolsky
2
@IgorGanapolsky Anda dapat membaca ini - stackoverflow.com/questions/21086307/…
roottraveller
Mempertahankan HashMap lebih mahal daripada TreeMap. Karena HashMap menciptakan ember tambahan yang tidak perlu.
Abdul
64

Selain apa yang dikatakan izb, HashMapmemungkinkan nilai null, sedangkan Hashtabletidak.

Perhatikan juga bahwa Hashtablememperluas Dictionarykelas, yang sebagai negara Javadocs , sudah usang dan telah digantikan oleh Mapantarmuka.

matt b
sumber
3
tapi itu tidak membuat HashTable menjadi usang bukan?
Pacerier
@Pacerier HashTable sudah usang sejak Java 1.7.
Majid Ali Khan
62

Lihatlah grafik ini. Ini memberikan perbandingan antara struktur data yang berbeda bersama dengan HashMapdan Hashtable. Perbandingannya tepat, jelas dan mudah dimengerti.

Matriks Koleksi Java

Sujan
sumber
49

Hashtablemirip dengan HashMapdan memiliki antarmuka yang serupa. Disarankan agar Anda menggunakan HashMap, kecuali jika Anda memerlukan dukungan untuk aplikasi lawas atau Anda perlu sinkronisasi, karena Hashtablesmetode disinkronkan. Jadi dalam kasus Anda karena Anda tidak multi-threading, HashMapsadalah taruhan terbaik Anda.

Miles D
sumber
36

Perbedaan utama lainnya antara hashtable dan hashmap adalah bahwa Iterator di HashMap gagal-cepat sementara enumerator untuk Hashtable tidak dan membuang ConcurrentModificationException jika ada Thread lain yang memodifikasi peta secara struktural dengan menambahkan atau menghapus elemen apa pun kecuali metode hapus () dari Iterator sendiri. Tetapi ini bukan perilaku yang dijamin dan akan dilakukan oleh JVM pada upaya terbaik. "

Sumber saya: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html

Neerja
sumber
36

Di samping semua aspek penting lainnya yang telah disebutkan di sini, Collections API (misalnya antarmuka Peta) sedang dimodifikasi sepanjang waktu agar sesuai dengan tambahan "terbaru dan terbesar" untuk spesifikasi Java.

Misalnya, bandingkan iterasi Java 5 Map:

for (Elem elem : map.keys()) {
  elem.doSth();
}

versus pendekatan Hashtable lama:

for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
  Elem elem = (Elem) en.nextElement();
  elem.doSth();
}

Di Jawa 1.8, kami juga berjanji untuk dapat membangun dan mengakses HashMaps seperti dalam bahasa skrip lama yang baik:

Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];

Perbarui: Tidak, mereka tidak akan mendarat di 1.8 ... :(

Apakah peningkatan koleksi Project Coin akan berada di JDK8?

pwes
sumber
34

Hashtabledisinkronkan, sedangkan HashMaptidak. Itu membuat Hashtablelebih lambat dari Hashmap.

Untuk aplikasi non-utas, gunakan HashMapkarena tidak sama dalam hal fungsi.

izb
sumber
30
  • HashTable disinkronkan, jika Anda menggunakannya dalam satu utas, Anda dapat menggunakan HashMap , yang merupakan versi yang tidak disinkronkan. Objek yang tidak disinkronkan seringkali sedikit lebih berkinerja. Ngomong-ngomong jika beberapa utas mengakses HashMap secara bersamaan, dan setidaknya satu utas memodifikasi peta secara struktural, itu harus disinkronkan secara eksternal. Youn dapat membungkus peta yang tidak disinkronkan dengan yang disinkronkan menggunakan:

    Map m = Collections.synchronizedMap(new HashMap(...));
  • HashTable hanya dapat berisi objek non-null sebagai kunci atau sebagai nilai. HashMap dapat berisi satu kunci nol dan nilai nol.

  • Iterator yang dikembalikan oleh Map adalah gagal-cepat, jika peta secara struktural diubah kapan saja setelah iterator dibuat, dengan cara apa pun kecuali melalui metode hapus iterator sendiri, iterator akan melempar a ConcurrentModificationException. Dengan demikian, dalam menghadapi modifikasi bersamaan, iterator gagal dengan cepat dan bersih, daripada mengambil risiko perilaku non-deterministik yang sewenang-wenang pada waktu yang tidak ditentukan di masa depan. Sedangkan Enumerasi yang dikembalikan oleh metode kunci dan elemen Hashtable tidak cepat gagal.

  • HashTable dan HashMap adalah anggota Java Collections Framework (sejak Java 2 platform v1.2, HashTable dipasang untuk mengimplementasikan antarmuka Peta).

  • HashTable dianggap sebagai kode lawas, dokumentasi menyarankan untuk menggunakan ConcurrentHashMap sebagai pengganti Hashtable jika diinginkan implementasi yang sangat konkuren yang aman secara bersamaan.

  • HashMap tidak menjamin urutan elemen dikembalikan. Untuk HashTable saya kira itu sama tetapi saya tidak sepenuhnya yakin, saya tidak menemukan sumber daya yang jelas menyatakan itu.

alain.janinm
sumber
30

HashMapdan Hashtablememiliki perbedaan algoritmik yang signifikan juga. Tidak ada yang menyebutkan ini sebelumnya jadi itu sebabnya saya membawanya. HashMapakan membuat tabel hash dengan kekuatan dua ukuran, meningkatkannya secara dinamis sehingga Anda memiliki paling banyak sekitar delapan elemen (tabrakan) di setiap bucket dan akan mengaduk elemen dengan sangat baik untuk tipe elemen umum. Namun demikianHashtable penerapannya memberikan kontrol yang lebih baik dan lebih baik atas hashing jika Anda tahu apa yang Anda lakukan, yaitu Anda dapat memperbaiki ukuran tabel menggunakan misalnya bilangan prima terdekat dengan ukuran domain nilai Anda dan ini akan menghasilkan kinerja yang lebih baik daripada HashMap yaitu lebih sedikit tabrakan untuk beberapa kasus.

Terpisah dari perbedaan nyata yang dibahas secara luas dalam pertanyaan ini, saya melihat Hashtable sebagai mobil "penggerak manual" di mana Anda memiliki kontrol yang lebih baik atas hashing dan HashMap sebagai mitra "penggerak otomatis" yang umumnya akan bekerja dengan baik.

SkyWalker
sumber
27

Berdasarkan info di sini , saya akan merekomendasikan pergi dengan HashMap. Saya pikir keuntungan terbesar adalah bahwa Java akan mencegah Anda dari memodifikasinya saat Anda mengulanginya, kecuali Anda melakukannya melalui iterator.

pkaeding
sumber
5
Itu sebenarnya tidak mencegahnya, itu hanya mendeteksi dan melempar kesalahan.
Bart van Heukelom
1
Saya cukup yakin ini akan melempar ConncurrentModificationException sebelum koleksi yang mendasarinya dimodifikasi, meskipun saya bisa saja salah.
pkaeding
Ini akan berusaha untuk mendeteksi modifikasi bersamaan dan melemparkan pengecualian. Tetapi jika Anda melakukan sesuatu dengan utas, itu tidak bisa membuat janji. Apa pun bisa terjadi, termasuk kerusakan .
cHao
24

A Collection- kadang-kadang disebut wadah - hanyalah sebuah objek yang mengelompokkan beberapa elemen menjadi satu unit. Collections digunakan untuk menyimpan, mengambil, memanipulasi, dan mengkomunikasikan data agregat. Kerangka kerja koleksi W adalah arsitektur terpadu untuk mewakili dan memanipulasi koleksi.

The HashMap JDK1.2dan Hashtable JDK1.0, keduanya digunakan untuk mewakili sekelompok objek yang diwakili <Key, Value>berpasangan. Setiap <Key, Value>pasangan disebut Entryobjek. Pengumpulan Entri disebut dengan objek HashMapdan Hashtable. Kunci dalam koleksi harus unik atau khas. [seperti yang digunakan untuk mengambil nilai yang dipetakan kunci tertentu. nilai dalam koleksi dapat diduplikasi.]


« Anggota Superclass, Legacy and Collection Framework

Hashtable adalah kelas warisan yang diperkenalkan di JDK1.0, yang merupakan subkelas dari kelas Kamus. From JDK1.2Hashtable direkayasa ulang untuk mengimplementasikan antarmuka Peta untuk membuat anggota kerangka koleksi. HashMap adalah anggota Java Collection Framework sejak awal pendahuluannya di JDK1.2. HashMap adalah subkelas dari kelas 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 { ... }

« Kapasitas awal dan Load factor

Kapasitas adalah jumlah ember di tabel hash, dan kapasitas awal hanyalah kapasitas pada saat tabel hash dibuat. Perhatikan bahwa tabel hash terbuka: dalam kasus " hashcollision", satu ember menyimpan banyak entri, yang harus dicari secara berurutan. Load factor adalah ukuran seberapa penuh tabel hash diizinkan dapatkan sebelum kapasitasnya meningkat secara otomatis.

HashMap membuat tabel hash kosong dengan kapasitas awal default (16) dan load factor default (0,75). Sedangkan Hashtable membangun hashtable kosong dengan kapasitas awal default (11) dan load factor / fill ratio (0,75).

Peta Hash & Hashtable

« Modifikasi struktural dalam kasus tabrakan hash

HashMap, Hashtabledalam kasus tabrakan hash mereka menyimpan entri peta dalam daftar tertaut. Dari Java8 untukHashMap jika hash bucket tumbuh melampaui ambang tertentu, ember itu akan beralih dari linked list of entries to a balanced tree. yang meningkatkan kinerja kasus terburuk dari O (n) ke O (log n). Saat mengonversi daftar ke pohon biner, kode hash digunakan sebagai variabel percabangan. Jika ada dua kode hash yang berbeda dalam ember yang sama, satu dianggap lebih besar dan pergi ke kanan pohon dan yang lainnya ke kiri. Tetapi ketika kedua kode hash sama, HashMapmengasumsikan bahwa kunci sebanding, dan membandingkan kunci untuk menentukan arah sehingga beberapa urutan dapat dipertahankan. Ini adalah praktik yang baik untuk membuat kunciHashMap sebanding . Pada menambahkan entri jika ukuran ember mencapaiTREEIFY_THRESHOLD = 8konversi daftar entri yang ditautkan ke pohon seimbang, pada penghapusan entri kurang dariTREEIFY_THRESHOLD dan paling banyak UNTREEIFY_THRESHOLD = 6akan mengubah pohon seimbang ke daftar entri yang ditautkan. Java 8 SRC , stackpost

« Pengumpulan-lihat iterasi, Gagal-Cepat dan Gagal-Aman

    +--------------------+-----------+-------------+
    |                    | Iterator  | Enumeration |
    +--------------------+-----------+-------------+
    | Hashtable          | fail-fast |    safe     |
    +--------------------+-----------+-------------+
    | HashMap            | fail-fast | fail-fast   |
    +--------------------+-----------+-------------+
    | ConcurrentHashMap  |   safe    |   safe      |
    +--------------------+-----------+-------------+

Iteratoradalah gagal-cepat di alam. yaitu ia melempar ConcurrentModificationException jika koleksi diubah saat iterasi selain dari itu sendiri menghapus () metode. Dimana Enumerationsifatnya aman-gagal. Itu tidak membuang pengecualian jika koleksi diubah saat iterasi.

Menurut Java API Docs, Iterator selalu lebih disukai daripada Enumeration.

CATATAN: Fungsi antarmuka Enumerasi diduplikasi oleh antarmuka Iterator. Selain itu, Iterator menambahkan operasi penghapusan opsional, dan memiliki nama metode yang lebih pendek. Implementasi baru harus mempertimbangkan menggunakan Iterator dalam preferensi untuk Enumerasi.

Di Java 5 diperkenalkan Antarmuka ConcurrentMap : ConcurrentHashMap- ConcurrentMapimplementasi yang sangat konkuren, kinerja tinggi yang didukung oleh tabel hash. Implementasi ini tidak pernah memblokir ketika melakukan pengambilan dan memungkinkan klien untuk memilih tingkat konkurensi untuk pembaruan. Ini dimaksudkan sebagai pengganti drop-in untuk Hashtable: selain menerapkan ConcurrentMap, ia mendukung semua metode "warisan" yang khas Hashtable.

  • Setiap HashMapEntrynilai s adalah stabil sehingga memastikan konsistensi baik gandum untuk modifikasi berpendapat dan selanjutnya berbunyi; setiap pembacaan mencerminkan pembaruan yang paling baru selesai

  • Iterator dan Enumeration Fail Safe - mencerminkan keadaan di beberapa titik sejak penciptaan iterator / enumerasi; ini memungkinkan pembacaan simultan dan modifikasi dengan biaya pengurangan konsistensi. Mereka tidak membuang ConcurrentModificationException. Namun, iterator dirancang hanya untuk digunakan oleh satu utas pada satu waktu.

  • Suka Hashtabletapi tidak seperti HashMap, kelas ini tidak mengizinkan null digunakan sebagai kunci atau nilai.

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 Dan Null Values

HashMapmemungkinkan maksimum satu kunci nol dan sejumlah nilai nol. Dimana as Hashtabletidak memungkinkan bahkan satu kunci nol dan nilai nol, jika kunci atau nilai nol maka itu melempar NullPointerException. Contoh

« Disinkronkan, Utas Aman

Hashtabledisinkronkan secara internal. Oleh karena itu, sangat aman untuk digunakan Hashtabledalam aplikasi multi-ulir. Dimana as HashMaptidak disinkronkan secara internal. Oleh karena itu, tidak aman untuk digunakan HashMapdalam aplikasi multi-ulir tanpa sinkronisasi eksternal. Anda dapat menyinkronkan secara eksternal HashMapmenggunakan Collections.synchronizedMap()metode.

« Performa

Seperti Hashtabledisinkronkan secara internal, ini membuat Hashtablesedikit lebih lambat daripada HashMap.


@Lihat

Yash
sumber
18

Untuk aplikasi berulir, Anda dapat sering pergi dengan ConcurrentHashMap- tergantung pada persyaratan kinerja Anda.

Tim Howland
sumber
17

1. Hashmapdan HashTablekeduanya menyimpan kunci dan nilai.

2. Hashmapdapat menyimpan satu kunci sebagai null. Hashtabletidak bisa menyimpan null.

3. HashMaptidak disinkronkan tetapi Hashtabledisinkronkan.

4. HashMapdapat disinkronkan denganCollection.SyncronizedMap(map)

Map hashmap = new HashMap();

Map map = Collections.SyncronizedMap(hashmap);
Rahul Tripathi
sumber
16

Terlepas dari perbedaan yang telah disebutkan, perlu dicatat bahwa sejak Java 8, HashMapsecara dinamis menggantikan Node (daftar tertaut) yang digunakan dalam setiap bucket dengan TreeNodes (pohon merah-hitam), sehingga meskipun tabrakan hash tinggi ada, kasus terburuk saat pencarian adalah

O (log (n)) untuk HashMap Vs O (n) di Hashtable.

* Peningkatan tersebut belum diterapkan Hashtable, tapi hanya untuk HashMap, LinkedHashMap, dan ConcurrentHashMap.

FYI, saat ini,

  • TREEIFY_THRESHOLD = 8 : jika ember berisi lebih dari 8 node, daftar tertaut diubah menjadi pohon seimbang.
  • UNTREEIFY_THRESHOLD = 6 : ketika ember menjadi terlalu kecil (karena dihapus atau diubah ukurannya) pohon dikonversi kembali ke daftar tertaut.
Kostas Chalkias
sumber
14

Ada 5 diferensiasi dasar dengan HashTable dan HashMaps.

  1. Peta memungkinkan Anda untuk mengulang dan mengambil kunci, nilai, dan kedua pasangan nilai kunci juga, Di mana HashTable tidak memiliki semua kemampuan ini.
  2. Di Hashtable ada fungsi berisi (), yang sangat membingungkan untuk digunakan. Karena arti dari mengandung sedikit menyimpang. Apakah itu berarti mengandung kunci atau mengandung nilai? sulit dipahami. Hal yang sama di Maps kami memiliki fungsi ContainsKey () dan ContainsValue (), yang sangat mudah dimengerti.
  3. Dalam hashmap Anda dapat menghapus elemen saat iterasi, dengan aman. di mana karena tidak mungkin dalam hashtables.
  4. HashTable secara default disinkronkan, sehingga dapat digunakan dengan banyak utas dengan mudah. Sedangkan HashMaps tidak disinkronkan secara default, sehingga dapat digunakan hanya dengan utas tunggal. Tetapi Anda masih dapat mengonversi HashMap untuk disinkronkan dengan menggunakan Koleksi menggunakan fungsi sinkronisasi peta (Peta m).
  5. HashTable tidak akan mengizinkan kunci nol atau nilai nol. Sedangkan HashMap memungkinkan satu kunci nol, dan beberapa nilai nol.
pengguna1923551
sumber
13

Kontribusi kecil saya:

  1. Perbedaan pertama dan paling signifikan antara Hashtabledan HashMapadalah bahwa, HashMaptidak aman-aman sedangkan Hashtablekoleksi-aman-aman.

  2. Perbedaan penting kedua antara Hashtabledan HashMapadalah kinerja, karena HashMaptidak disinkronkan kinerjanya lebih baik daripada Hashtable.

  3. Perbedaan ketiga pada Hashtablevs HashMapadalah bahwa Hashtablekelas usang dan Anda harus menggunakan ConcurrentHashMapdi tempat Hashtabledi Jawa.

Shreyos Adikari
sumber
11

HashMap: Ini adalah kelas yang tersedia di dalam paket java.util dan digunakan untuk menyimpan elemen dalam format kunci dan nilai.

Hashtable: Ini adalah kelas warisan yang diakui di dalam kerangka koleksi.

Ankit
sumber
Jika ya, harus dalam komentar bukan sebagai jawaban.
Manikant Gautam
10

HashTable adalah kelas warisan di jdk yang seharusnya tidak digunakan lagi. Ganti penggunaannya dengan ConcurrentHashMap . Jika Anda tidak memerlukan keamanan utas, gunakan HashMap yang bukan threadsafe tetapi lebih cepat dan menggunakan lebih sedikit memori.

jontejj
sumber
Karena saya pikir jawaban yang lain, pada saat itu, tidak menolak HashTable tetapi menjelaskan bahwa itu adalah threadsafe. Yang benar adalah bahwa segera setelah Anda melihat HashTable dalam kode, Anda harus menggantinya dengan ConcurrentHashMap tanpa melewatkan irama. Dan jika keamanan utas bukan masalah maka HashMap dapat digunakan untuk sedikit meningkatkan kinerja.
jontejj
10
  1. Hashtable disinkronkan sedangkan HashMap tidak.
  2. Perbedaan lain adalah bahwa iterator di HashMapgagal-aman sedangkan enumerator untuk Hashtabletidak. Jika Anda mengubah peta saat iterasi, Anda akan tahu.
  3. HashMapmengizinkan nilai nol di dalamnya, sementara Hashtabletidak.
raja
sumber
3
Iterator HashMap adalah gagal-cepat bukan gagal-aman. Itulah mengapa kami memiliki ConcurrentHashMap yang memungkinkan modifikasi saat iterasi. Lihat posting ini journaldev.com/122/…
Pankaj
9

HashMap dan HashTable

  • Beberapa poin penting tentang HashMap dan HashTable. baca detail di bawah ini.

1) Hashtable dan Hashmap mengimplementasikan antarmuka java.util.Map 2) Baik Hashmap dan Hashtable adalah koleksi berbasis hash. dan mengerjakan hashing. jadi ini adalah kesamaan dari HashMap dan HashTable.

  • Apa perbedaan antara HashMap dan HashTable?

1) Perbedaan pertama adalah HashMap bukan thread aman Sementara HashTable adalah ThreadSafe
2) HashMap adalah kinerja yang lebih baik karena tidak aman thread. sementara performa Hashtable tidak lebih baik karena aman untuk thread. jadi beberapa utas tidak dapat mengakses Hashtable secara bersamaan.

JegsVala
sumber
2
Terpilih karena jawaban ini tidak benar dalam beberapa aspek. Hashtable tidak mengimplementasikan antarmuka Peta, tetapi hanya memperluas kelas Kamus, yang sudah usang.
Yannis Sermetziadis
8

Hashtable:

Hashtable adalah struktur data yang mempertahankan nilai pasangan kunci-nilai. Itu tidak mengizinkan nol untuk kunci dan nilai. Anda akan mendapatkan NullPointerExceptionjika Anda menambahkan nilai nol. Ini disinkronkan. Jadi itu datang dengan biayanya. Hanya satu utas yang dapat mengakses HashTable pada waktu tertentu.

Contoh :

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 seperti Hashtable tetapi juga menerima pasangan nilai kunci. Memungkinkan null untuk kunci dan nilai-nilai. Kinerjanya lebih baik lebih baik daripada HashTable, karena memang demikianunsynchronized .

Contoh:

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

    }
}
IntelliJ Amiya
sumber
5

HashMapditiru dan karena itu dapat digunakan GWT client codesedangkan Hashtabletidak.

pong
sumber
Apakah itu deskripsi komprehensif tentang perbedaan antara keduanya?
IgorGanapolsky
Ya (sic!). Itu semua yang perlu diketahui pengembang GWT tentang hal itu.
pong
5

Topik lama dan klasik, hanya ingin menambahkan blog bermanfaat ini yang menjelaskan ini:

http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/

Blog oleh Manish Chhabra

5 perbedaan utama antara HashMap dan Hashtable

HashMap dan Hashtable keduanya mengimplementasikan antarmuka java.util.Map tetapi ada beberapa perbedaan yang harus dipahami oleh pengembang Java untuk menulis kode yang lebih efisien. Pada platform Java 2 v1.2, kelas Hashtable dipasang untuk mengimplementasikan antarmuka Peta, menjadikannya anggota Java Collections Framework.

  1. Salah satu perbedaan utama antara HashMap dan Hashtable adalah bahwa HashMap tidak disinkronkan sedangkan Hashtable disinkronkan, yang berarti Hashtable aman untuk digunakan bersama dan dapat dibagi di antara beberapa utas tetapi HashMap tidak dapat dibagi antara beberapa utas tanpa sinkronisasi yang tepat. Java 5 memperkenalkan ConcurrentHashMap yang merupakan alternatif dari Hashtable dan memberikan skalabilitas yang lebih baik daripada Hashtable di Java. Sinkronisasi berarti hanya satu utas yang dapat memodifikasi tabel hash pada satu titik waktu. Pada dasarnya, ini berarti bahwa utas apa pun sebelum melakukan pembaruan pada hashtable harus mendapatkan kunci pada objek sementara yang lain akan menunggu kunci dirilis.

  2. Kelas HashMap kira-kira setara dengan Hashtable, kecuali bahwa itu mengizinkan nol. (HashMap memungkinkan nilai nol sebagai kunci dan nilai sedangkan Hashtable tidak mengizinkan nol).

  3. Perbedaan signifikan ketiga antara HashMap vs Hashtable adalah bahwa Iterator di HashMap adalah iterator gagal-cepat sedangkan enumerator untuk Hashtable tidak dan melempar ConcurrentModificationException jika ada Thread lain yang memodifikasi peta secara struktural dengan menambahkan atau menghapus elemen apa pun kecuali penghapusan Iterator sendiri ( ) metode. Tapi ini bukan perilaku yang dijamin dan akan dilakukan oleh JVM pada upaya terbaik. Ini juga merupakan perbedaan penting antara Pencacahan dan Iterator di Jawa.

  4. Satu lagi perbedaan penting antara Hashtable dan HashMap adalah karena keamanan dan sinkronisasi utas Hashtable jauh lebih lambat daripada HashMap jika digunakan dalam lingkungan berulir tunggal. Jadi, jika Anda tidak memerlukan sinkronisasi dan HashMap hanya digunakan oleh satu utas, itu menjalankan Hashtable di Jawa.

  5. HashMap tidak menjamin bahwa urutan peta akan tetap konstan seiring waktu.

Perhatikan bahwa HashMap dapat disinkronkan oleh

Map m = Collections.synchronizedMap(hashMap);

Dalam Ringkasan ada perbedaan yang signifikan antara Hashtable dan HashMap di Jawa misalnya keamanan dan kecepatan thread dan berdasarkan itu hanya menggunakan Hashtable jika Anda benar-benar membutuhkan keamanan thread, jika Anda menjalankan Java 5 pertimbangkan menggunakan ConcurrentHashMap di Java.

Night0
sumber
ConcurrentHashMap tidak dibaca-disinkronkan, sedangkan Hashtable adalah. Jadi jika Anda memiliki banyak operasi baca yang terjadi bersamaan dengan penulisan, Hashtable akan membantu Anda lebih baik jika Anda peduli dengan integritas data.
IgorGanapolsky
5

HashMap dan Hashtable keduanya digunakan untuk menyimpan data dalam bentuk kunci dan nilai. Keduanya menggunakan teknik hashing untuk menyimpan kunci unik. ut ada banyak perbedaan antara kelas HashMap dan Hashtable yang diberikan di bawah ini.

masukkan deskripsi gambar di sini

DeC
sumber
Ringkasan visual yang bagus!
Nadjib Mami