Soru HashMap ve Hashtable arasındaki farklar?


Arasındaki farklar nelerdir HashMap ve bir Hashtable Java'da?

Dişli olmayan uygulamalar için hangisi daha verimli?


3122
2017-09-02 20:12


Menşei


HashTable, Java 1.7'de geçersizdir ve ConcurrentMap uygulamasını kullanmanız önerilir - MissFiona


Cevaplar:


Arasında birkaç fark var HashMap ve Hashtable Java’da:

  1. Hashtable olduğu senkronize, buna karşılık HashMap değil. Bu yapar HashMap Eşlenmemiş Nesneler genellikle eşitlenmemiş olanlardan daha iyi performans gösterirken, iş parçacıklı olmayan uygulamalar için daha iyidir.

  2. Hashtable izin vermiyor null anahtarlar veya değerler. HashMap birine izin verir null anahtar ve herhangi bir sayı null değerler.

  3. HashMap'ın alt sınıflarından biri LinkedHashMapBu nedenle, öngörülebilir yineleme sırasını (varsayılan olarak ekleme sırası) istiyorsanız, kolayca takas HashMap bir için LinkedHashMap. Kullanıyor olmanız bu kadar kolay olmaz Hashtable.

Senkronizasyon sizin için bir sorun olmadığı için tavsiye ederim HashMap. Senkronizasyon bir sorun olursa, ayrıca ConcurrentHashMap.


3207
2017-09-02 23:02



HashMap iş parçacığı güvenliğini sağlamak istiyorsanız, Collections.synchronizedMap(). - Rok Strniša
Ayrıca iplik güvenliği için naif yaklaşımın Hashtable ("her yöntemin senkronize edilmesi, herhangi bir eşzamanlılık sorununa dikkat etmelidir!") çok şey yapar daha da kötüsü dişli uygulamalar için. Harici olarak senkronizasyondan daha iyisin HashMap (ve sonuçları hakkında düşünmek) veya ConcurrentMap Uygulama (ve eşzamanlı API için eşzamanlılık için yararlanma). Alt satır: kullanmanın tek nedeni Hashtable eski bir API (yaklaşık 1996) bunu gerektirir. - erickson
HashMap aslında kullanıldıklarında threadSafe kodunu yazmak için programlayıcıya esneklik sağlar. Nadiren ConcurrentHashMap veya HashTable gibi bir iş parçacığı güvenli koleksiyona ihtiyacım oldu. İhtiyacım olan şey, senkronize edilmiş bir blokta belirli işlevler veya belirli ifadelerin threadafe olması. - Gaurava Agarwal
Hashtable eski ve güvenli olmayan bir ortam için HashMap kullanıyoruz. İş parçacığı güvenliğine ihtiyacınız varsa, Collections.synchronizedMap () öğesini kullanabilir veya hashtable olan daha verimli olan ConcurrentHashMap'i kullanabilirsiniz. - Maneesh Kumar
Bu modası geçmiş ama kullanımdan kaldırılmamış ve neden bunun olduğunu merak ediyorum. Bu sınıfı kaldırmanın (ve aynı nedenlerden dolayı Vector) çok fazla varolan kodu bozacağını ve @Deprecated ile ek açıklama yapacağını tahmin etmeliyim ki, görünüşe göre orada olmayan kodu kaldırmak niyetinde olacaktır. - Jilles van Gurp


Yanıtların çoğunun Hashtable'ın senkronize olduğunu belirtiyor. Pratikte bu sizi çok az satın alır.  Eşzamanlama, erişimci / mutator yöntemlerinde eşzamanlı olarak haritadan ekleyerek veya çıkarırken iki parçayı durduracaktır, ancak gerçek dünyada çoğu zaman ek senkronizasyona ihtiyacınız olacaktır.

Çok yaygın bir deyim "kontrol et ve sonra" yerine koymaktır - diğer bir deyişle, Harita'ya bir giriş aramalı ve eğer mevcut değilse ekleyiniz. Hashtable veya HashMap'i kullanmanızın hiçbir şekilde bir atom işlemi olmadığı anlamına gelmez.

Eşzamanlı olarak senkronize edilmiş bir HashMap şu yollarla elde edilebilir:

Collections.synchronizedMap(myMap);

Ama ihtiyacınız olan bu mantığı doğru bir şekilde uygulamak için ek senkronizasyon şeklinde:

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

Haritanın ek senkronizasyon yoluyla değiştirilmesini engellemediğiniz sürece bir Hashtable'ın girişlerini (veya Collections.synchronizedMap tarafından elde edilen bir HashMap) yineleme bile güvenli değildir.

Uygulamaları ConcurrentMap arayüz (örneğin ConcurrentHashMap) Bunları dahil ederek bazılarını çöz iş parçacığı güvenli onay-sonra-eylem semantiği gibi:

ConcurrentMap.putIfAbsent(key, value);

583
2017-09-03 11:00



Ayrıca, bir HashMap değiştirilirse, işaret eden yineleyicilerin geçersiz hale getirildiğini unutmayın. - Chris K
Yineleyici ConcurrentModificationException'ı atar, doğru mu? - Bhushan
Yani senkronize (myMap) {...} ve ConcurrentHashMap arasında iş parçacığı güvenliği açısından bir fark var mı? - telebog
Çok doğru, aynı şeyi burada açıklamaya çalıştım ..lovehasija.com/2012/08/16/... - Love Hasija
@Bhushan: En iyi çabaya dayanacak, bu garantili bir davranış değildir: docs.oracle.com/javase/7/docs/api/java/util/HashMap.html - Matt Stephenson


Hashtable eski kod olarak kabul edilir. Hakkında bir şey yok Hashtable kullanarak yapılamaz HashMap veya türevleri HashMapBu yüzden, yeni kod için, geri dönüş için herhangi bir gerekçe görmüyorum Hashtable.


288
2018-06-25 01:46



Hashtable javadoc'tan (vurgu ekledi): "Java 2 platformu v1.2'den itibaren, bu sınıf Harita arayüzünü uygulamak için yeniden donatıldı, onu Java Koleksiyonlar Çerçevesinin bir üyesi yapmak"Ancak, bu eski bir kod olduğu doğrudur. Senkronizasyonun tüm faydaları, Collections.synchronizedMap (HashMap) ile daha verimli bir şekilde elde edilebilir. (Vectors'in Collections.synchronizedList (ArrayList) 'in eski bir sürümü olduğu gibi.) - Kip
@ aberrant80: maalesef ikisi arasında bir seçiminiz yok ve J2ME için programlama yaparken Hashtable kullanmanız gerekiyor ... - pwes
bu cevap silinmelidir. yanlış bilgiler içeriyor ve çok fazla not var. - anon58192932
@ anon58192932 Bunu düzeltmek için soruyu düzenlemek mümkün mü? - GC_
Poster @ aberrant80 veya bir yönetici tarafından dikkat çekmeliyiz. İşaretleme yardımcı olabilir - şimdi bunu deneyeceğim. - anon58192932


Bu soru, adayın koleksiyon sınıflarının doğru kullanımını anlayıp anlamadığını ve mevcut alternatif çözümlerden haberdar olup olmadığını kontrol etmek için görüşme sırasında sıklıkla sorulur.

  1. HashMap sınıfı, eşitlenmemiş olması ve boş değerlere izin vermesi dışında Hashtable'a kabaca eşittir. (HashMode null değerlerine anahtar ve değer olarak izin verirken Hashtable, boş değerlere izin vermez).
  2. HashMap, haritanın sırasının zamanla sabit kalacağını garanti etmez.
  3. Hashtable senkronize değilken HashMap senkronize değil.
  4. Hashtable'daki yineleyici hata-güvenli iken Hashtable için numaralandırıcı, Iterator'ın kendi remove () yönteminin dışında herhangi bir öğe ekleyerek veya çıkartarak başka bir iş parçacığı yapısal olarak değiştirirse ConcurrentModificationException'ı atar ve atar. Ancak bu garantili bir davranış değildir ve JVM tarafından en iyi şekilde yapılacaktır.

Bazı Önemli Terimlerle İlgili Not

  1. Senkronize, tek bir iş parçacığının hash tablosunu bir noktada değiştirebileceği anlamına gelir. Temel olarak, bir hashtable üzerinde bir güncelleme yapmadan önce herhangi bir iş parçacığı, bir nesne üzerinde bir kilit elde etmek zorunda kalacaktır, diğerleri kilitlenmek için beklemek için bekleyecektir anlamına gelir.
  2. Arıza güvenliği, yineleyici bağlamından kaynaklanır. Bir toplama nesnesinde bir yineleyici oluşturulduysa ve başka bir iş parçacığı, toplama nesnesini "yapısal olarak" değiştirmeye çalışırsa, eşzamanlı bir değişiklik istisnası atılır. "Thread" yöntemini çağırmak için diğer thread'lar için de mümkündür, çünkü koleksiyon "yapısal olarak" değiştirilmez. Ancak, "set" çağırmadan önce, koleksiyon yapısal olarak değiştirilmiş, "IllegalArgumentException" atılacaktır.
  3. Yapısal olarak modifikasyon, haritanın yapısını etkili bir şekilde değiştirebilen elemanın silinmesi veya yerleştirilmesi anlamına gelir.

HashMap tarafından senkronize edilebilir

Map m = Collections.synchronizeMap(hashMap);

Harita, yineleme için doğrudan destek yerine Koleksiyon görünümleri sağlar  Numaralandırma nesneleri ile. Koleksiyon görünümleri büyük ölçüde geliştirir  Bu bölümde daha sonra ele alındığı gibi arayüzün ifadesi.  Harita, anahtarlar, değerler veya anahtar / değer çiftleri üzerinde yineleme yapmanızı sağlar;  Hashtable üçüncü seçeneği sağlamıyor. Harita güvenli bir yol sağlar  yineleme ortasında girişleri kaldırmak için; Hashtable yapmadı.  Son olarak Harita, Hashtable arayüzünde küçük bir eksikliği giderir.  Hashtable, içeriğinde bulunan bir yönteme sahiptir;  Hashtable belirli bir değeri içerir. İsmini göz önünde bulundurursan, bunu beklersin.  Hashtable belirli bir anahtarı içeriyorsa true değerini döndürme yöntemi  Anahtar, bir Hashtable için birincil erişim mekanizmasıdır. Harita  arabirim, yöntemi yeniden adlandırarak bu karışıklık kaynağını ortadan kaldırır  containsValue. Ayrıca, bu arayüzün tutarlılığını artırır -  içerirValue parallels içerirKey.

Harita Arayüzü


148
2017-10-04 06:39



Bu cevap, en az 2 önemli gerçek yanlışlık içeriyor. Kesinlikle bu çok sayıda oyu hak etmiyor. - Stephen C
1) HashMap'in yineleyicileri arıza güvenli DEĞİLDİR. Başarısızlar. Bu iki terim arasında anlam bakımından büyük bir fark vardır. 2) yoktur set üzerinde işlem HashMap. 3) put(...) operasyon atmayacak IllegalArgumentException önceki bir değişiklik olsaydı. 4) başarısız-hızlı davranış HashMap  Ayrıca Bir eşleştirmeyi değiştirirseniz oluşur. 5) Başarısız davranış olduğu garantili. (Garanti edilmeyen şey, HashTable eşzamanlı bir değişiklik yaparsanız. Gerçek davranış ... öngörülemez.) - Stephen C
6) Hashtable Harita öğelerinin sırasının da zaman içinde sabit olacağını garanti etmez. (Belki de kafa karıştırıcıdır Hashtable ile LinkedHashMap.) - Stephen C
Başka herkes gerçekten bu günlerde öğrencilerin koleksiyonların "senkronize sürümlerini" almanın bir şekilde bileşik işlemleri harici olarak senkronize etmek zorunda kalmayacağınız anlamına geldiğine dair ciddi bir fikre kapılmasından gerçekten endişe duyuyorlar. Bu varlığa en sevdiğim örnek thing.set(thing.get() + 1); özellikle daha önce hiç korunmasız olarak sürprizlerle yenilerini yakalamayan, özellikle get() ve set() senkronize yöntemler. Birçoğu sihir bekliyorlar.
HashMap'teki yineleyiciler başarısız değil - Abdul


HashMap: Bir uygulaması Map bir diziyi indekslemek için karma kodları kullanan arabirim. Hashtable: Merhaba, 1998 aradı. Koleksiyonlarının API'sini geri istiyorlar.

Cidden olsa, uzak durmaktan daha iyi olursun Hashtable tamamen. Tek iş parçacıklı uygulamalar için, senkronizasyon ek yüküne ihtiyacınız yoktur. Son derece eşzamanlı uygulamalar için, paranoyak senkronizasyon açlık, kilitlenme veya gereksiz çöp toplama duraklamalarına yol açabilir. Tim Howland'ın işaret ettiği gibi, ConcurrentHashMap yerine.


107
2017-09-02 23:14



Bu aslında mantıklı. ConcurrentHashMaps size senkronizasyon ve hata ayıklama özgürlüğü verir. - prap19


Unutmayın ki HashTable Java Koleksiyonlar Çerçevesi (JCF) kullanılmadan önceki eski sınıftı ve daha sonra, Map arayüz. Öyleydi Vector ve Stack.

Bu nedenle, her zaman JCF'de her zaman daha iyi bir alternatif olduğu için onlardan uzak durun. diğerleri de işaret ettiği gibi.

İşte Java koleksiyonu hile sayfası faydalı bulacaksın. Gri bloğun, eski HashTable, Vector ve Stack sınıfını içerdiğine dikkat edin.

enter image description here


104
2018-03-25 08:58





İzb'in dediğine ek olarak, HashMap boş değerlere izin verirken, Hashtabledeğil.

Ayrıca dikkat edin Hashtable genişletir Dictionary sınıf olarak Javadocs devlet, eski ve yerini almıştır Map arayüz.


58
2017-09-02 20:30



Ancak bu HashTable eski yapmak değil mi? - Pacerier


Bu tabloya bir bakın. HashMap ve Hashtable ile birlikte farklı veri yapıları arasında karşılaştırmalar sağlar. Karşılaştırma kesin, açık ve anlaşılması kolay.

Java Koleksiyonu Matrisi


50
2017-11-20 05:35



teşekkürler, şimdi senaryoda neyi seçeceğimi biliyorum. - Well Smith


Hashtable benzer HashMap ve benzer bir arayüze sahiptir. Kullanmanız önerilir HashMapEski uygulamalar için desteğe ihtiyacınız olmadıkça veya senkronizasyona ihtiyacınız varsa, Hashtables yöntemler senkronize edilir. Yani sizin durumunuzda çok iş parçacığı olmadığından HashMaps en iyi bahistirsiniz.


39
2017-09-02 20:25





Hashtable ve hashmap arasındaki bir diğer önemli fark, Hashtable'daki yineleyicinin başarısız olmasıdır. Hashtable için numaralandırıcı ise, başka bir Thread, Iterator'un kendi remove () yöntemi dışında herhangi bir öğe ekleyerek veya çıkartarak yapısal olarak değiştirirse ConcurrentModificationException öğesini atar. Ancak bu garantili bir davranış değildir ve JVM tarafından en iyi şekilde yapılacaktır. ”

Kaynağım: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html


31
2017-09-08 06:40