HashMap ve Hashtable arasındaki farklar?


3750

Java'da a HashMapve a Hashtablearasındaki farklar nelerdir ?

Dişsiz uygulamalar için hangisi daha verimlidir?


17
HashTable Java 1.7'de kullanılmıyor ve ConcurrentMap uygulamasını kullanmanız önerilir
MissFiona

@MissFiona Hayır, ConcurrentMapolduğu değil Soru parçacığı / eşzamanlılık anlamına gelen “dişli olmayan uygulamalar” bir sorun değildir söylediği gibi, burada gerekli.
Basil Bourque

Yanıtlar:


3774

Java arasında HashMapve HashtableJava'da birkaç fark vardır :

  1. Hashtablebir senkronize oysa HashMapdeğildir. Bu, HashMapsenkronize olmayan Nesneler genellikle senkronize olanlardan daha iyi performans gösterdiğinden, iş parçacığı olmayan uygulamalar için daha iyi olur.

  2. Hashtablenullanahtarlara veya değerlere izin vermez . HashMapbir nulltuşa ve herhangi bir sayıda nulldeğere izin verir .

  3. Hashmap en alt sınıflarından biri LinkedHashMapyani (varsayılan olarak kampanya siparişini olan) öngörülebilir yineleme düzenini istediğimiz durumunda, kolayca dışarı takas olabilir HashMapbir için LinkedHashMap. Eğer kullanırsanız bu hiç de kolay olmazdı Hashtable.

Senkronizasyon sizin için bir sorun olmadığından tavsiye ederim HashMap. Senkronizasyon bir sorun haline gelirse, şunlara da bakabilirsiniz ConcurrentHashMap.


84
Bir HashMap iş parçacığı için güvenli yapmak istiyorsanız kullanın Collections.synchronizedMap().
Rok Strniša

275
Ben de Hashtable("her yöntemi senkronize herhangi bir eşzamanlılık sorunları halletmeli!") İş parçacığı güvenli naif yaklaşım dişli uygulamalar için çok daha kötü hale yorum . Harici olarak senkronize etmek HashMap(ve sonuçları düşünmek) veya bir ConcurrentMapuygulama kullanmak (ve eşzamanlılık için genişletilmiş API'sını kullanmak) daha iyidir . Alt satır: Kullanmanın tek nedeni Hashtableeski bir API'nin (yaklaşık 1996'dan itibaren) gerektirdiği zamandır.
erickson

8
HashMap, programcıya gerçekte kullandıklarında threadSafe kodu yazma esnekliği sağlar. ConcurrentHashMap veya HashTable gibi bir iş parçacığı güvenli koleksiyonuna nadiren ihtiyacım vardı. Ne gerekli belirli işlevler kümesi veya iş parçacığı için eşitlenmiş bir blok içinde belirli ifadeler.
Gaurava Agarwal

2
Hashtable kullanılmıyor ve iş parçacığı olmayan güvenli ortamlar için HashMap kullanıyoruz. İş parçacığı güvenliğine ihtiyacınız varsa, Collections.synchronizedMap () veya hashtable'dan daha verimli olan ConcurrentHashMap kullanabilirsiniz.
Maneesh Kumar

1
Eski ama kullanımdan kaldırılmadı ve bunun neden olduğunu merak ediyorum. Bu sınıf (ve Vector aynı nedenlerle) kaldırma çok fazla mevcut kodu kıracağını tahmin ediyorum ve @Deprecated ile açıklama ek olarak görünüşte orada olmayan kodu kaldırmak için bir niyet ima eder.
Jilles van Gurp

682

Yanıtların çoğunun Hashtable'ın senkronize edildiğini belirttiğini unutmayın. Pratikte bu çok az satın alır. Eşitleme erişimci üzerinde / mutasyon yöntemleri aynı anda haritaya ekleme veya çıkarma iki iş parçacığı durur, ancak gerçek dünyada genellikle ek senkronizasyon gerekir.

Çok yaygın bir deyim "kontrol et ve sonra koy" - yani, içinde bir giriş aramak Mapve yoksa zaten eklemek. Ya da kullansanız Hashtableda hiçbir şekilde bir atomik işlem değildir HashMap.

Eşzamanlı olarak senkronize HashMapedilenler şu yollarla elde edilebilir:

Collections.synchronizedMap(myMap);

Ancak bu mantığı doğru bir şekilde uygulamak için formun ek senkronizasyonuna ihtiyacınız vardır :

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

Ek senkronizasyon yoluyla değiştirilmesini önlemediğiniz sürece, Hashtablebir girişinin (veya HashMaptarafından elde edilen Collections.synchronizedMap) üzerinden yineleme yapmak güvenli değildir Map.

Uygulamaları ConcurrentMap(örneğin arayüzü ConcurrentHashMap) da dahil olmak üzere, bu bazı çözmek iplik güvenli bir ara sonra-hareket semantik gibi:

ConcurrentMap.putIfAbsent(key, value);

53
Ayrıca, bir HashMap değiştirilirse, ona işaret eden yineleyicilerin geçersiz hale getirildiğini unutmayın.
Chris K

3
Senkronize (myMap) {...} ve ConcurrentHashMap arasında güvenli iş parçacığı açısından herhangi bir fark var mı?
telebog

3
Çok doğru, burada açıklamaya çalıştım .. lovehasija.com/2012/08/16/…
Love Hasija

@Bhushan: En iyi çaba temelinde atılacak, bu garantili davranış değil: docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Matt Stephenson

Birkaç yıl boyunca bir JVM geliştirme ekibinin ortasında olan Hashtable'ın iç senkronizasyonunun, tehlikeli eşzamanlı kod yazarken müşterinin koduna düzgün bir şekilde işaret etmek için en azından kullanışlı olduğunu söyleyebilirim. Sebep eşzamanlı değişiklik olduğunda HashMap (ve dolayısıyla "açıkça" bir JDK / JVM hatası) içinde birkaç hata şikayeti aldık.
Hot Licks

363

Hashtableeski kod olarak kabul edilir. Bunun hakkında hiçbir şey Hashtablekullanılamaz HashMapveya türetme yapılamaz HashMap, bu yüzden yeni kod için geri dönmek için herhangi bir gerekçe görmüyorum Hashtable.


101
Hashtable javadoc'tan (vurgu eklenmiştir): "Java 2 platformu v1.2'den itibaren, bu sınıf Harita arabirimini uygulamak ve böylece onu Java Koleksiyonlar Çerçevesi'nin bir üyesi haline getirmek için güçlendirildi ." Ancak, bunun eski kod olduğu konusunda haklısınız. Senkronizasyonun tüm avantajları Collections.synchronizedMap (HashMap) ile daha verimli bir şekilde elde edilebilir. (Vector, Collections.synchronizedList'in (ArrayList) eski bir versiyonudur.)
Kip

15
@ aberrant80: ne yazık ki ikisi arasında bir seçim var ve J2ME için programlama yaparken Hashtable kullanmak zorunda ...
pwes

6
bu cevap silinmelidir. yanlış bilgi içeriyor ve çok sayıda oy var.
anon58192932

@ anon58192932 Sorunu düzeltmek için düzenlemek mümkün mü?
GC_

1
İşaretleyerek @ aberrant80 posterinin veya bir yöneticinin dikkatini çekmek zorundayız. İşaretleme yardımcı olabilir - şimdi deneyeceğim.
anon58192932

189

Bu soru genellikle mülakatta adayın toplama sınıflarının doğru kullanımını anlayıp anlamadığını ve mevcut alternatif çözümlerin farkında olup olmadığını kontrol etmeleri istenir.

  1. HashMapSınıf eşdeğerdir Hashtableolmayan senkronize ve izinleri nulls olması dışında. ( HashMapanahtar ve değer olarak null değerlere Hashtableizin verirken nulls'ye izin vermez ).
  2. HashMap haritanın sırasının zaman içinde sabit kalacağını garanti etmez.
  3. HashMapsenkronize değil Hashtable, senkronize edilir.
  4. Yineleyici HashMapbaşarısız olduğu için güvenli Hashtabledeğildir ve ConcurrentModificationExceptionbaşka bir iş parçacığı, Iteratorkendi remove() yöntemi dışında herhangi bir öğeyi ekleyerek veya kaldırarak haritayı yapısal olarak değiştirirse atar . Ancak bu garantili bir davranış değildir ve JVM tarafından en iyi çaba ile yapılacaktır.

Bazı Önemli Terimler Hakkında Not:

  1. Senkronize edilmiş, bir tablodaki bir karma tabloyu yalnızca bir iş parçacığında değiştirebileceği anlamına gelir. Temel olarak, bir güncelleştirme gerçekleştirmeden önce herhangi bir iş parçacığının Hashtablenesne üzerinde bir kilit alması gerekirken, diğerleri kilidin serbest bırakılmasını bekleyecektir.
  2. Arıza güvenliği, yineleyiciler bağlamında önemlidir. Bir toplama nesnesi üzerinde 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. setToplama "yapısal olarak" değiştirmediği için diğer iş parçacıkları için yöntem çağırmak mümkündür . Ancak, aramadan önce set, koleksiyon yapısal olarak değiştirilmişse, IllegalArgumentExceptionatılacaktır.
  3. Yapısal olarak modifikasyon, haritanın yapısını etkili bir şekilde değiştirebilecek elemanın silinmesi veya eklenmesi anlamına gelir.

HashMap tarafından senkronize edilebilir

Map m = Collections.synchronizeMap(hashMap);

Harita, Numaralandırma nesneleri aracılığıyla yineleme için doğrudan destek yerine Koleksiyon görünümleri sağlar. Koleksiyon görünümleri, bu bölümün ilerleyen kısımlarında ele alındığı gibi arayüzün anlamlılığını büyük ölçüde artırır. Harita, anahtarlar, değerler veya anahtar / değer çiftleri üzerinde yineleme yapmanızı sağlar; Hashtableüçüncü seçeneği sunmaz. Harita, yinelemenin ortasında girişleri kaldırmak için güvenli bir yol sağlar; Hashtableolmadı. Son olarak, Harita Hashtablearayüzdeki küçük bir eksikliği giderir . Hashtable, Hashtableverilen bir değer içeriyorsa true değerini döndüren, include adında bir yöntem içerir . Adı göz önüne alındığında, Hashtableverilen bir anahtar varsa bu yöntemin true değerini döndürmesini beklersiniz , çünkü anahtar a için birincil erişim mekanizmasıdır Hashtable. Harita arayüzü, 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 - containsValueparaleller containsKey.

Harita Arayüzü


19
Bu cevap en az 2 önemli olgusal yanlışlık içeriyor. Bu kadar çok oyu kesinlikle hak etmiyor.
Stephen C

58
1) HashMap yineleyicileri arıza korumalı DEĞİLDİR. Başarısızdırlar. Bu iki terim arasında anlam bakımından büyük bir fark vardır. 2) seta üzerinde işlem yapılmaz HashMap. 3) Daha önce bir değişiklik yapılmışsa put(...)işlem fırlatılamaz IllegalArgumentException. 4) Bir eşlemeyi değiştirirseniz , hata-hızlı davranışı HashMap da ortaya çıkar. 5) başarısız hızlı davranışı olduğu garanti edilir. (Garantili olmayan, HashTableeşzamanlı bir değişiklik yaparsanız bir davranışıdır. Gerçek davranış ... öngörülemez.)
Stephen C

25
6) Hashtableharita öğelerinin sırasının zaman içinde sabit kalacağını garanti etmez. (Belki de karıştırıyorsun Hashtableile LinkedHashMap.)
Stephen C

4
Bu günlerde öğrencilerin koleksiyonların "senkronize edilmiş sürümlerini" almanın bir şekilde bileşik işlemleri harici olarak senkronize etmeniz gerekmediği anlamına gelen hatalı bir fikir aldığından gerçekten endişelenen var mı? Bu ve benim en sevdiğim örnek thing.set(thing.get() + 1);, özellikle ve get()ve set()senkronize yöntemler ise, tamamen korunmasız olarak sürprizlerle yenileri yakalamadan daha sık olan . Birçoğu sihir bekliyor.

HashMap'teki yineleyiciler hataya dayanıklı değildir
Abdul

130

HashMap: MapDiziyi dizine eklemek için karma kodları kullanan arabirimin uygulaması . Hashtable: Merhaba, 1998 aradı. Koleksiyon API'larını geri istiyorlar.

Ciddi olsa da, Hashtabletamamen uzak kalmak daha iyi . Tek iş parçacıklı uygulamalar için fazladan senkronizasyon yüküne ihtiyacınız yoktur. Eşzamanlı uygulamalar için paranoyak senkronizasyonu açlığa, çıkmaza veya gereksiz çöp toplama duraklamalarına yol açabilir. Tim Howland'ın belirttiği gibi, ConcurrentHashMapbunun yerine kullanabilirsiniz .


Bu aslında mantıklı. ConcurrentHashMaps size senkronizasyon özgürlüğü verir ve hata ayıklama çok daha kolaydır.
19:11

1
Bu, Java'ya veya tüm karma harita uygulamasına özgü mü?

125

HashTableJava Collections Framework (JCF) kullanılmadan önce eski bir sınıf olduğunu ve daha sonra Maparabirimi uygulamak için sonradan yükseltildiğini unutmayın . Öyleydi Vectorve Stack.

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

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

resim açıklamasını buraya girin


72

Gönderilmiş çok iyi bir cevap var. Birkaç yeni nokta ekliyorum ve özetliyorum.

HashMapve Hashtableher ikisi de verileri anahtar ve değer biçiminde depolamak için kullanılır . Her ikisi de benzersiz anahtarları saklamak için hashing tekniğini kullanıyor. Ancak, aşağıda verilen HashMap ve Hashtable sınıfları arasında birçok fark vardır.

HashMap

  1. HashMapsenkronize değil. İş parçacığı için güvenli değildir ve uygun eşitleme kodu olmadan birçok iş parçacığı arasında paylaşılamaz.
  2. HashMap bir null anahtarına ve birden fazla null değerine izin verir.
  3. HashMap JDK 1.2'de tanıtılan yeni bir sınıftır.
  4. HashMap hızlı.
  5. Biz HashMapbu kodu çağırarak senkronize yapabilirsiniz
    Map m = Collections.synchronizedMap(HashMap);
  6. HashMap Yineleyici tarafından geçilir.
  7. Yineleyici HashMapbaşarısız.
  8. HashMap AbstractMap sınıfını devralır.

hashtable'a

  1. Hashtablesenkronize edilir. İş parçacığı için güvenlidir ve birçok iş parçacığı ile paylaşılabilir.
  2. Hashtable boş anahtar veya değere izin vermez.
  3. Hashtable eski bir sınıftır.
  4. Hashtable yavaş.
  5. Hashtable dahili olarak senkronize edilir ve senkronize edilemez.
  6. Hashtable Enumerator ve Iterator tarafından geçilir.
  7. Numaralandırıcı girişi Hashtablehızlı değil.
  8. Hashtable Sözlük sınıfını devralır.

Daha fazla okuma Java'da HashMap ve Hashtable arasındaki fark nedir?

resim açıklamasını buraya girin


Hemen hemen bu cevapta kapsanmıştır (kopya) - stackoverflow.com/a/39785829/432903 .
prayagupd

Neden ~ " Hashtable eski bir sınıf " diyorsunuz? Bunun için destekleyici belgeler nerede.
IgorGanapolsky

2
@IgorGanapolsky bunu okuyabilirsiniz - stackoverflow.com/questions/21086307/…
roottraveller 29:17

HashMap'in bakımı TreeMap'ten daha pahalıdır. Çünkü HashMap gereksiz ek kovalar oluşturur.
Abdul

64

İzb'in söylediklerine ek olarak HashMap, null değerlere izin verirken, izin Hashtablevermez.

Ayrıca Javadocs durumu olarak eski olan ve arabirim tarafından değiştirilen sınıfı Hashtablegenişletir .DictionaryMap


3
ama bu HashTable'ı eskimiş yapmaz mı?
Pacerier

@Pacerier HashTable, Java 1.7'den beri kullanılmıyor.
Majid Ali Khan

62

Bu tabloya bir göz atın. HashMapVe ile birlikte farklı veri yapıları arasında karşılaştırmalar sağlar Hashtable. Karşılaştırma kesin, net ve anlaşılması kolaydır.

Java Koleksiyon Matrisi


49

Hashtableile benzerdir HashMapve benzer bir arayüze sahiptir. Yöntemler HashMapsenkronize olduğundan eski uygulamalar için desteğe ihtiyacınız yoksa veya senkronizasyona ihtiyacınız yoksa kullanmanız önerilir Hashtables. Bu durumda, çok iş parçacıklı olmadığınız HashMapsiçin en iyi seçiminizdir .


36

Hashtable ve hashmap arasındaki bir diğer önemli fark, HashMap içindeki Iterator'ın hızlı olması, Hashtable için numaralandırıcı olmaması ve başka bir iş parçacığının Iterator'ın kendi remove () yöntemi dışında herhangi bir öğeyi ekleyerek veya kaldırarak haritayı yapısal olarak değiştirmesi durumunda ConcurrentModificationException'ı atmasıdır. Ancak bu garantili bir davranış değildir ve JVM tarafından en iyi çaba ile yapılacaktır. "

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


36

Burada daha önce bahsedilen tüm diğer önemli özelliklerin yanı sıra, Koleksiyonlar API'sı (ör. Harita arayüzü), Java spesifikasyonlarına "en son ve en büyük" eklemelere uyacak şekilde sürekli olarak değiştirilmektedir.

Örneğin, Java 5 Harita yinelemesini karşılaştırın:

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

Eski Hashtable yaklaşımına karşı:

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

Java 1.8'de, iyi eski komut dosyası dillerinde olduğu gibi HashMaps'i oluşturabileceğimiz ve bunlara erişebileceğimize söz veriyoruz:

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

Güncelleme: Hayır, 1.8'e inmeyecekler ... :(

Project Coin'in koleksiyon geliştirmeleri JDK8'de mi olacak?


34

Hashtablesenkronize edilir, oysa senkronize HashMapedilmez. Bu Hashtabledaha yavaş yapar Hashmap.

İş parçacığı olmayan uygulamalar için, HashMapaksi takdirde işlevsellik açısından aynı oldukları için kullanın .


30
  • HashTable senkronize edilir, tek bir iş parçacığında kullanıyorsanız , senkronize edilmemiş bir sürüm olan HashMap'i kullanabilirsiniz . Senkronize olmayan nesneler genellikle biraz daha performanslıdır. Bu arada, birden çok iş parçacığı aynı anda bir HashMap'e erişiyorsa ve iş parçacıklarından en az biri haritayı yapısal olarak değiştiriyorsa, harici olarak senkronize edilmesi gerekir. Senkronize edilmemiş bir haritayı aşağıdakileri kullanarak senkronize edilmiş bir haritaya sarabilirsiniz:

    Map m = Collections.synchronizedMap(new HashMap(...));
  • HashTable yalnızca null olmayan bir nesneyi anahtar veya değer olarak içerebilir. HashMap bir null anahtar ve null değerler içerebilir.

  • Harita tarafından döndürülen yineleyiciler hızlıdır, yineleyici oluşturulduktan sonra harita yapısal olarak değiştirilirse, yineleyicinin kendi kaldırma yöntemi dışında herhangi bir şekilde yineleyici a atar ConcurrentModificationException. Böylece, eşzamanlı modifikasyon karşısında, yineleyici gelecekte belirsiz bir zamanda keyfi, deterministik olmayan davranışları riske atmak yerine hızlı ve temiz bir şekilde başarısız olur. Oysa Hashtable'ın anahtarları ve elemanları yöntemleri tarafından döndürülen Numaralandırmalar hızlı değildir.

  • HashTable ve HashMap, Java Collections Framework'ün üyesidir (Java 2 platformu v1.2'den beri, Map arabirimini uygulamak için HashTable uyarlanmıştır).

  • HashTable eski kod olarak kabul edilir; belgelere, iş parçacığı açısından güvenli, yüksek eşzamanlı bir uygulama isteniyorsa, Hashtable yerine ConcurrentHashMap kullanılması önerilir .

  • HashMap öğelerin döndürülme sırasını garanti etmez. HashTable için sanırım aynı ama tamamen emin değilim, açıkça ifade eden kaynak bulamıyorum.


30

HashMapve Hashtableönemli algoritmik farklılıklara sahipler. Daha önce hiç kimse bundan bahsetmedi, bu yüzden onu gündeme getiriyorum. HashMapiki büyüklükte bir karma tablo oluşturacak, herhangi bir kovada en fazla sekiz eleman (çarpışma) olacak şekilde dinamik olarak artıracak ve elemanları genel eleman tipleri için çok iyi karıştıracaktır. Bununla birlikte, Hashtableuygulama ne yaptığınızı biliyorsanız, tablo karmaşası üzerinde daha iyi ve daha iyi kontrol sağlar, yani, örneğin alan adınızın değerlerine en yakın asal sayıyı kullanarak tablo boyutunu düzeltebilirsiniz ve bu, HashMap'e göre daha iyi performansla sonuçlanır, yani daha az çarpışma bazı durumlar için.

Bu soruda yoğun olarak tartışılan bariz farklılıklardan ayrı olarak, Hashtable'ı, karma işlem üzerinde daha iyi kontrole sahip olduğunuz bir "manuel sürücü" arabası olarak ve genellikle iyi performans gösterecek "otomatik sürücü" karşılığı olarak HashMap'ı görüyorum.


27

Buradaki bilgilere dayanarak HashMap ile gitmenizi tavsiye ederim. Bence en büyük avantajı, yineleyici aracılığıyla yapmazsanız, Java'nın onu yinelediğinizde değiştirmenizi önleyeceğidir.


5
Aslında bunu engellemez, sadece algılar ve bir hata atar.
Bart van Heukelom

1
Yanlış olsa da, temel koleksiyon değiştirilmeden önce bir ConncurrentModificationException atacak eminim.
pkaeding

Bu olacak girişimi eşzamanlı değişiklik algılar ve bir özel durum için. Ancak, iş parçacığıyla bir şey yapıyorsanız, söz veremezsiniz. Kesinlikle kırılma dahil her şey olabilir .
cHao

24

A Collection- bazen kap olarak da adlandırılır - birden çok öğeyi tek bir birimde gruplayan bir nesnedir. CollectionToplam verileri depolamak, almak, değiştirmek ve iletmek için kullanılır. Bir koleksiyon çerçevesi W , koleksiyonları temsil etmek ve değiştirmek için birleşik bir mimaridir.

HashMap JDK1.2Ve Hashtable'a JDK1.0, hem de temsil edilen nesne grubunu temsil etmek için kullanılır <Key, Value>çifti. Her <Key, Value>çifte Entrynesne denir . Girişleri koleksiyon nesnesi ile anılır HashMapve Hashtable. Bir koleksiyondaki anahtarlar benzersiz veya farklı olmalıdır. [eşlenmiş bir değeri belirli bir anahtar almak için kullanıldığından. bir koleksiyondaki değerler çoğaltılabilir.]


« Üst Sınıf, Eski ve Koleksiyon Çerçevesi üyesi

Hashtable, JDK1.0Dictionary sınıfının bir alt sınıfı olan, tanıtılan eski bir sınıftır. Gönderen JDK1.2Hashtable uygulamak için tasarlanmış yeniden olduğunu Harita arayüzü toplama çerçevesinin bir üyesi yapmak. HashMap, Java Collection Framework'ün kuruluşundan itibaren üyesidir JDK1.2. HashMap, AbstractMap sınıfının alt sınıfıdır.

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 { ... }

« Başlangıç ​​kapasitesi ve Yük faktörü

Kapasite, karma tablosundaki kova sayısıdır ve ilk kapasite, karma tablonun oluşturulduğu andaki kapasitedir. Karma tablonun açık olduğuna dikkat edin: " hashcollision" durumunda, tek bir kova birden fazla girişi saklar ve bunlar ardışık olarak aranmalıdır. Yük faktörü, hash tablosunun kapasitesi otomatik olarak artırılmadan önce ne kadar dolu olmasına izin verildiğinin bir ölçüsüdür.

HashMap, varsayılan başlangıç ​​kapasitesine (16) ve varsayılan yük faktörüne (0.75) sahip boş bir karma tablo oluşturur . Hashtable olarak varsayılan başlangıç ​​kapasitesi (11) ve yük faktörü / dolum oranı (0.75) ile boş hashtable oluşturur .

Hash Haritası ve Hashtable

« Karma çarpışma durumunda yapısal değişiklik

HashMap, HashtableKarma çarpışma yaşanması durumunda bunlar bağlı listelerde haritası girişlerini depolar. Java8'denHashMap karma kova belirli bir eşiğin üzerine çıkarsa, o kova geçiş yapar linked list of entries to a balanced tree. O (n) 'den O (log n)' ye en kötü durum performansını geliştirir. Listeyi ikili ağaca dönüştürürken, dallanma değişkeni olarak hashcode kullanılır. Aynı kovada iki farklı hashcode varsa, biri daha büyük olarak kabul edilir ve ağacın sağına, diğeri sola gider. Ancak her iki hashcode eşit HashMapolduğunda, anahtarların karşılaştırılabilir olduğunu varsayar ve bazı siparişlerin korunabilmesi için yönü belirlemek için anahtarı karşılaştırır. Anahtarları HashMap karşılaştırılabilir kılmak iyi bir uygulamadır . Kepçe boyutuna ulaşırsa giriş ekleme hakkındaTREEIFY_THRESHOLD = 8Bağlantılı girişler listesini dengeli bir ağaca dönüştürmek, girişleri daha az TREEIFY_THRESHOLD ve en fazla kaldırmak, UNTREEIFY_THRESHOLD = 6dengeli ağacı bağlantılı girişler listesine yeniden dönüştürmek olacaktır. Java 8 SRC , yığın dizisi

« Koleksiyon görünümü yineleme, Hızlı ve Başarısız

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

Iteratordoğada başarısız bir hızdır. yani, bir koleksiyon kendi remove () yönteminden başka bir yineleme sırasında değiştirilirse ConcurrentModificationException öğesini atar. Nerede olarak Enumerationarıza emniyetli doğasında. Bir koleksiyon yineleme sırasında değiştirilirse herhangi bir istisna atmaz.

Java API Dokümanlarına göre, Numaralandırma yerine Yineleyici her zaman tercih edilir.

NOT: Numaralandırma arabiriminin işlevselliği Yineleyici arabirimi tarafından çoğaltılır. Buna ek olarak, Iterator isteğe bağlı bir kaldırma işlemi ekler ve daha kısa yöntem adlarına sahiptir. Yeni uygulamalar, Numaralandırma yerine Iterator kullanmayı düşünmelidir.

In Java 5 ConcurrentMap Arayüz tanıtıldı : ConcurrentHashMap- son derece eşzamanlı, yüksek performanslı ConcurrentMapbir karma tablo tarafından yedeklenmiş uygulanmasını. Bu uygulama, alım gerçekleştirirken hiçbir zaman engellemez ve istemcinin güncellemeler için eşzamanlılık seviyesini seçmesine izin verir. Aşağıdakiler için bir yedek yedek olarak tasarlanmıştır Hashtable: uygulamaya ek olarak ConcurrentMap, tüm "eski" yöntemleri de destekler Hashtable.

  • Her bir HashMapEntrys değeri uçucudur, bu nedenle devam eden değişiklikler ve müteakip okumalar için ince tanecik tutarlılığı sağlar; her okuma en son tamamlanan güncellemeyi yansıtır

  • Yineleyiciler ve Numaralandırmalar Güvenli Değildir - yineleyici / numaralandırmanın oluşturulmasından bu yana durumu bir noktada yansıtır; bu, düşük tutarlılık pahasına eşzamanlı okumalara ve değişikliklere izin verir. ConcurrentModificationException'ı atmazlar. Ancak, yineleyiciler aynı anda yalnızca bir iş parçacığı tarafından kullanılmak üzere tasarlanmıştır.

  • Benzeri Hashtableama aksine HashMap, bu sınıf null değerinin anahtar veya değer olarak kullanılmasına izin vermez.

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

« Boş Tuşlar ve Boş Değerler

HashMapmaksimum bir null anahtarına ve herhangi bir sayıda null değerine izin verir. As Hashtable, tek bir null anahtarına ve null değerine bile izin vermezse, anahtar veya null değeri NullPointerException atar. Misal

« Senkronize, İş Parçacığı Kasası

Hashtabledahili olarak senkronize edilir. Bu nedenle, Hashtableçok iş parçacıklı uygulamalarda kullanmak çok güvenlidir . Olduğu gibi HashMapdahili olarak senkronize edilmez. Bu nedenle, HashMapharici senkronizasyon olmadan çok iş parçacıklı uygulamalarda kullanmak güvenli değildir . Yöntemi HashMapkullanarak harici olarak senkronize edebilirsiniz Collections.synchronizedMap().

« Performans

Gibi Hashtableiçten senkronize edilir, bu yapar Hashtablebiraz daha yavaş HashMap.


@Görmek


18

Dişli uygulamalar için, genellikle performans gereksinimlerinize bağlı olarak ConcurrentHashMap ile kurtulabilirsiniz.


17

1. Hashmapve HashTablehem anahtar hem de değer saklayın.

2. Hashmapbir anahtar olarak saklayabilirsiniz null. Hashtablesaklanamaz null.

3. HashMapsenkronize değil Hashtable, senkronize.

4. HashMapile senkronize edilebilirCollection.SyncronizedMap(map)

Map hashmap = new HashMap();

Map map = Collections.SyncronizedMap(hashmap);

16

Hali hazırda zikredilen farklılıklardan, Java 8 yana olduğunu belirtmek gerekir HashMapdinamik yüksek karma çarpışmalar, en kötü durumda bulunsa bile, böylece, TreeNodes (kırmızı-siyah ağacı) ile her bir bölümdeki kullanılan düğümleri (bağlantılı liste) yerini alır zaman arama olduğunu

HashMap Vs O (n) için O (log (n)) Hashtable.

* Yukarıda belirtilen iyileştirme için uygulanmamıştır Hashtableyok, ama sadece HashMap, LinkedHashMapve ConcurrentHashMap.

FYI, şu anda,

  • TREEIFY_THRESHOLD = 8 : bir kova 8'den fazla düğüm içeriyorsa, bağlantılı liste dengeli bir ağaca dönüştürülür.
  • UNTREEIFY_THRESHOLD = 6 : bir kova çok küçük olduğunda (kaldırma veya yeniden boyutlandırma nedeniyle) ağaç tekrar bağlantılı listeye dönüştürülür.

14

HashTable ve HashMaps ile 5 temel fark vardır.

  1. Haritalar anahtarları, değerleri ve her iki anahtar / değer çiftini de yinelemenize ve almanıza olanak tanır. HashTable'ın tüm bu özelliklere sahip olmadığı yerlerde.
  2. Hashtable'da kullanımı çok kafa karıştırıcı olan () işlevi vardır. Çünkü içeriğin anlamı biraz sapıyor. Anahtar içerdiği veya değer içerdiği anlamına mı geliyor? anlamak zor. Haritalar'da da aynı şey, anlaşılması çok kolay olan ContainsKey () ve ContainsValue () işlevlerine sahibiz.
  3. Hashmap'ta elementi tekrarlarken güvenle kaldırabilirsiniz. nerede hashtable mümkün değil.
  4. HashTable'lar varsayılan olarak senkronize edilir, bu nedenle birden çok iş parçacığı ile kolayca kullanılabilir. HashMaps olarak varsayılan olarak senkronize edilmediğinde, yalnızca tek bir iş parçacığı ile kullanılabilir. Ancak yine de Koleksiyonlar util sınıfının syncedMap (Map m) işlevini kullanarak HashMap'i senkronize edebilirsiniz.
  5. HashTable null anahtarlara veya null değerlere izin vermez. Burada HashMap olarak bir boş anahtar ve birden çok boş değer izin verir.

13

Benim küçük katkım:

  1. İlk ve en arasında farklı anlamlı Hashtableve HashMapdiğer bir deyişle, HashMapdeğil evreli süre Hashtablebir iş parçacığı uyumlu koleksiyon.

  2. Arasındaki İkinci önemli fark Hashtableve HashMapbu yana, performans HashMapdaha iyi daha gerçekleştirmek senkronize edilmez Hashtable.

  3. Üçüncü fark Hashtablevs HashMapyani Hashtableeskimiş sınıftır ve kullanmakta edilmelidir ConcurrentHashMapyerine HashtableJava.


11

HashMap: java.util paketinde bulunan bir sınıftır ve öğeyi anahtar ve değer biçiminde depolamak için kullanılır.

Hashtable: Koleksiyon çerçevesi içinde tanınan eski bir sınıftır.


Eğer öyleyse, cevap olarak değil yorumlarda olmalıdır.
manikant gautam

10

HashTable , artık kullanılmaması gereken jdk'de eski bir sınıftır. Kullanımlarını ConcurrentHashMap ile değiştirin . Eğer iplik güvenlik, kullanım ihtiyacınız yoksa HashMap değil ÅŸan ancak daha hızlı ve kullanımları daha az bellek.


Çünkü o zaman diğer cevapların HashTable'ı reddetmediğini, ancak bunun güvenli olduğunu açıkladığını düşündüm. Gerçek şu ki, HashTable'ı kodda gördüğünüz anda, bir ritmi atlamadan ConcurrentHashMap ile değiştirmelisiniz. İş parçacığı güvenliği bir endişe değilse, performansı biraz geliştirmek için HashMap kullanılabilir.
jontejj

10
  1. Hashtablesenkronize edilirken HashMapdeğil.
  2. Diğer bir fark ise, yineleyicinin HashMapnumaralandırıcısının başarısız olması için güvenli Hashtableolmamasıdır. Tekrarlarken haritayı değiştirirseniz bilirsiniz.
  3. HashMapiçinde null değerlere izin verirken izin Hashtablevermez.

3
HashMap yineleyici arıza hızlı değil arıza güvenli. Bu yüzden yineleme sırasında modifikasyona izin veren ConcurrentHashMap var. Bu yazıyı
Pankaj

9

HashMap ve HashTable

  • HashMap ve HashTable hakkında bazı önemli noktalar. lütfen aşağıdaki detayları okuyun.

1) Hashtable ve Hashmap, java.util.Map arayüzünü uygular. 2) Hashmap ve Hashtable, karma tabanlı koleksiyondur. ve karma üzerinde çalışıyor. yani bunlar HashMap ve HashTable'ın benzerliğidir.

  • HashMap ve HashTable arasındaki fark nedir?

1) İlk fark HashMap iş parçacığı güvenli değildir HashTable ThreadSafe iken
2) HashMap performans açısından daha iyi olduğu için iş parçacığı güvenli değildir. Hashtable performans akıllıca iplik güvenli olduğu için daha iyi değildir. bu nedenle birden fazla iş parçacığı aynı anda Hashtable'a erişemez.


2
Bu oylama bazı açılardan doğru olmadığından aşağı oy kullanıldı. Hashtable, Map arabirimini uygulamaz, ancak yalnızca eski olan Dictionary sınıfını genişletir.
Yannis Sermetziadis

8

Hashtable:

Hashtable , anahtar / değer çiftinin değerlerini koruyan bir veri yapısıdır. Hem anahtarlar hem de değerler için null değerine izin vermez. NullPointerExceptionBoş değer eklerseniz bir alırsınız . Senkronize edilir. Yani maliyeti ile geliyor. HashTable'a belirli bir zamanda yalnızca bir iş parçacığı erişebilir .

Örnek :

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 gibidir Hashtable ama aynı zamanda anahtar değer çiftini kabul eder. Hem anahtarlar hem de değerler için null değerine izin verir. Performansı daha iyi HashTable, çünkü öyle unsynchronized.

Misal:

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

HashMaptaklit ve bu nedenle de kullanılması mümkündür GWT client code, oysa Hashtabledeğildir.


Bu, iki apis arasındaki farkların kapsamlı bir açıklaması mı?
IgorGanapolsky

Evet (sic!). Tüm GWT geliştiricilerinin bunu bilmesi gerekiyor.
pong

5

Eski ve klasik konu, bunu açıklayan bu yararlı blog'u eklemek istiyorum:

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

Manish Chhabra tarafından paylaşılan mekanlar

HashMap ve Hashtable arasındaki 5 ana fark

HashMap ve Hashtable, java.util.Map arabirimini uygular, ancak Java geliştiricilerinin daha verimli kod yazmak için anlamaları gereken bazı farklılıklar vardır. Java 2 platformu v1.2'den itibaren, Hashtable sınıfı Harita arayüzünü uygulamak için uyarlandı ve bu da onu Java Koleksiyonlar Çerçevesinin bir üyesi haline getirdi.

  1. HashMap ve Hashtable arasındaki en büyük farklardan biri HashMap'in senkronize edilmemesidir, Hashtable senkronize edilir, bu da Hashtable'ın iş parçacığı için güvenli olduğu ve birden çok iş parçacığı arasında paylaşılabileceği, ancak HashMap'in uygun eşitleme olmadan birden çok iş parçacığı arasında paylaşılamayacağı anlamına gelir. Java 5, Hashtable'ın alternatifi olan ve Java'da Hashtable'dan daha iyi ölçeklenebilirlik sağlayan ConcurrentHashMap'i sundu. Temel olarak, bir hashtable üzerinde güncelleme yapmadan önce herhangi bir iş parçacığının nesne üzerinde bir kilit alması gerekeceği, diğerleri ise kilidin serbest bırakılmasını bekleyeceği anlamına gelir.

  2. HashMap sınıfı, null değerlerine izin vermesi dışında Hashtable ile kabaca eşdeğerdir. (HashMap null değerlere anahtar ve değer olarak izin verirken Hashtable null değerlerine izin vermez).

  3. HashMap ve Hashtable arasındaki üçüncü önemli fark, HashMap'teki Iterator'ın hızlı bir yineleyici olması, Hashtable için numaralandırıcı olmaması ve Iterator'ın kendi kaldırması dışında herhangi bir öğeyi ekleyerek veya kaldırarak haritayı yapısal olarak değiştirmesi durumunda ConcurrentModificationException'ı atmasıdır ( ) yöntem. Ancak bu garantili bir davranış değildir ve JVM tarafından en iyi çaba ile yapılacaktır. Bu aynı zamanda Java'da Numaralandırma ve Yineleyici arasındaki önemli bir farktır.

  4. Hashtable ve HashMap arasındaki diğer bir fark da iplik güvenliği ve senkronizasyonu nedeniyle Hashtable'ın Tek iş parçacıklı ortamda kullanılması durumunda HashMap'ten çok daha yavaş olmasıdır. Bu nedenle senkronizasyona ihtiyacınız yoksa ve HashMap yalnızca bir iş parçacığı tarafından kullanılıyorsa, Java'da Hashtable gerçekleştirir.

  5. HashMap, haritanın sırasının zaman içinde sabit kalacağını garanti etmez.

HashMap'in aşağıdakilerle senkronize edilebileceğini unutmayın:

Map m = Collections.synchronizedMap(hashMap);

Özet olarak, Java'da Hashtable ve HashMap arasında önemli farklar vardır, örneğin iş parçacığı güvenliği ve hız ve buna dayanarak Hashtable'ı sadece iş parçacığı güvenliğine ihtiyacınız varsa kullanın, Java 5 çalıştırıyorsanız Java'da ConcurrentHashMap kullanmayı düşünün.


ConcurrentHashMap okuma-senkronize edilmezken Hashtable öyle. Dolayısıyla, yazma işlemleriyle aynı anda yüksek miktarda okuma işleminiz varsa, veri bütünlüğünü önemsiyorsanız Hashtable size daha iyi hizmet eder.
IgorGanapolsky

5

HashMap ve Hashtable , verileri anahtar ve değer biçiminde depolamak için kullanılır. Her ikisi de benzersiz anahtarları saklamak için hashing tekniğini kullanıyor. ut Aşağıda verilen HashMap ve Hashtable sınıfları arasında birçok fark vardır.

resim açıklamasını buraya girin


Güzel görsel özet!
Nadjib Mami
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.