Hashtable v Javě
The Hashtable class implementuje hashovací tabulku, která mapuje klíče na hodnoty. Libovolný nenull objekt lze použít jako klíč nebo jako hodnotu. Pro úspěšné ukládání a načítání objektů z hashtable musí objekty použité jako klíče implementovat metodu hashCode a metodu rovná se.
Třída java.util.Hashtable je třída v Javě, která poskytuje datovou strukturu klíč-hodnota, podobnou rozhraní Map. Byl součástí původního rámce Java Collections a byl představen v Javě 1.0.
Třída Hashtable je však od té doby považována za zastaralou a její používání se obecně nedoporučuje. Je to proto, že byl navržen před zavedením frameworku Collections a neimplementuje rozhraní Map, což ztěžuje použití ve spojení s jinými částmi frameworku. Třída Hashtable je navíc synchronizována, což může mít za následek pomalejší výkon ve srovnání s jinými implementacemi rozhraní Map.
Obecně se místo třídy Hashtable doporučuje používat rozhraní Map nebo některou z jeho implementací (jako je HashMap nebo ConcurrentHashMap).
Zde je příklad, jak používat třídu Hashtable:
Jáva
import> java.util.Enumeration;> import> java.util.Hashtable;> public> class> Main {> > public> static> void> main(String[] args) {> > Hashtable hashtable => new> Hashtable();> > // Adding elements to the hashtable> > hashtable.put(> 'A'> ,> 1> );> > hashtable.put(> 'B'> ,> 2> );> > hashtable.put(> 'C'> ,> 3> );> > // Getting values from the hashtable> > int> valueA = hashtable.get(> 'A'> );> > System.out.println(> 'Value of A: '> + valueA);> > // Removing elements from the hashtable> > hashtable.remove(> 'B'> );> > // Enumerating the elements of the hashtable> > Enumeration keys = hashtable.keys();> > while> (keys.hasMoreElements()) {> > String key = keys.nextElement();> > System.out.println(> 'Key: '> + key +> ', Value: '> + hashtable.get(key));> > }> > }> }> |
Výstup
Value of A: 1 Key: A, Value: 1 Key: C, Value: 3
Závěrem lze říci, že i když třída Hashtable v Javě stále existuje a lze ji stále používat, obecně se doporučuje místo ní používat rozhraní Map nebo některou z jeho implementací.
Vlastnosti Hashtable
- Je podobný HashMap, ale je synchronizovaný.
- Hashtable ukládá pár klíč/hodnota do hashovací tabulky.
- V Hashtable zadáme objekt, který se používá jako klíč, a hodnotu, kterou chceme k tomuto klíči přiřadit. Klíč je poté hashován a výsledný hash kód je použit jako index, pod kterým je hodnota uložena v tabulce.
- Počáteční výchozí kapacita třídy Hashtable je 11, zatímco loadFactor je 0,75.
- HashMap neposkytuje žádný výčet, zatímco Hashtable poskytuje výčet, který není rychlý při selhání.
Prohlášení:
public class Hashtable extends Dictionary implements Map, Cloneable, Serializable
Parametry typu:
- K – typ klíčů spravovaných touto mapou
- V – typ mapovaných hodnot
Hierarchie Hashtable
Hashtable nástroje Serializovatelné , Klonovatelné , Mapa rozhraní a rozšiřuje Slovník . Přímé podtřídy jsou Properties , UIDefaults .
Konstruktéři:
Abychom vytvořili hashtable, musíme jej importovat java.util.Hashtable . Hashtable můžeme vytvořit různými způsoby.
1. Hashtable(): Tím se vytvoří prázdná hashovací tabulka s výchozím faktorem zatížení 0,75 a počáteční kapacitou je 11.
Hashtable ht = new Hashtable();
Jáva
// Java program to demonstrate> // adding elements to Hashtable> import> java.io.*;> import> java.util.*;> class> AddElementsToHashtable {> > public> static> void> main(String args[])> > {> > // No need to mention the> > // Generic type twice> > Hashtable ht1 => new> Hashtable();> > // Initialization of a Hashtable> > // using Generics> > Hashtable ht2> > => new> Hashtable();> > // Inserting the Elements> > // using put() method> > ht1.put(> 1> ,> 'one'> );> > ht1.put(> 2> ,> 'two'> );> > ht1.put(> 3> ,> 'three'> );> > ht2.put(> 4> ,> 'four'> );> > ht2.put(> 5> ,> 'five'> );> > ht2.put(> 6> ,> 'six'> );> > // Print mappings to the console> > System.out.println(> 'Mappings of ht1 : '> + ht1);> > System.out.println(> 'Mappings of ht2 : '> + ht2);> > }> }> |
Výstup
Mappings of ht1 : {3=three, 2=two, 1=one} Mappings of ht2 : {6=six, 5=five, 4=four} 2. Hashtable (int initialCapacity): Tím se vytvoří hashovací tabulka, která má počáteční velikost určenou parametrem initialCapacity a výchozí faktor zatížení je 0,75.
Hashtable ht = new Hashtable(int initialCapacity);
Jáva
// Java program to demonstrate> // adding elements to Hashtable> import> java.io.*;> import> java.util.*;> class> AddElementsToHashtable {> > public> static> void> main(String args[])> > {> > // No need to mention the> > // Generic type twice> > Hashtable ht1 => new> Hashtable(> 4> );> > // Initialization of a Hashtable> > // using Generics> > Hashtable ht2> > => new> Hashtable(> 2> );> > // Inserting the Elements> > // using put() method> > ht1.put(> 1> ,> 'one'> );> > ht1.put(> 2> ,> 'two'> );> > ht1.put(> 3> ,> 'three'> );> > ht2.put(> 4> ,> 'four'> );> > ht2.put(> 5> ,> 'five'> );> > ht2.put(> 6> ,> 'six'> );> > // Print mappings to the console> > System.out.println(> 'Mappings of ht1 : '> + ht1);> > System.out.println(> 'Mappings of ht2 : '> + ht2);> > }> }> |
Výstup
Mappings of ht1 : {3=three, 2=two, 1=one} Mappings of ht2 : {4=four, 6=six, 5=five} 3. Hashtable(int size, float fillRatio): Tato verze vytvoří hashovací tabulku, která má počáteční velikost určenou velikostí a poměrem plnění určeným pomocí fillRatio. fill ratio: V zásadě určuje, jak plná může být hašovací tabulka, než se její velikost změní směrem nahoru a její hodnota leží mezi 0,0 až 1,0.
Hashtable ht = new Hashtable(int size, float fillRatio);
Jáva
// Java program to demonstrate> // adding elements to Hashtable> import> java.io.*;> import> java.util.*;> class> AddElementsToHashtable {> > public> static> void> main(String args[])> > {> > // No need to mention the> > // Generic type twice> > Hashtable ht1> > => new> Hashtable(> 4> ,> 0> .75f);> > // Initialization of a Hashtable> > // using Generics> > Hashtable ht2> > => new> Hashtable(> 3> ,> 0> .5f);> > // Inserting the Elements> > // using put() method> > ht1.put(> 1> ,> 'one'> );> > ht1.put(> 2> ,> 'two'> );> > ht1.put(> 3> ,> 'three'> );> > ht2.put(> 4> ,> 'four'> );> > ht2.put(> 5> ,> 'five'> );> > ht2.put(> 6> ,> 'six'> );> > // Print mappings to the console> > System.out.println(> 'Mappings of ht1 : '> + ht1);> > System.out.println(> 'Mappings of ht2 : '> + ht2);> > }> }> |
Výstup
Mappings of ht1 : {3=three, 2=two, 1=one} Mappings of ht2 : {6=six, 5=five, 4=four} 4. Hashtable (Mapa m): Tím se vytvoří hashovací tabulka, která je inicializována prvky v m.
Hashtable ht = new Hashtable(Map m);
Jáva
// Java program to demonstrate> // adding elements to Hashtable> import> java.io.*;> import> java.util.*;> class> AddElementsToHashtable {> > public> static> void> main(String args[])> > {> > // No need to mention the> > // Generic type twice> > Map hm => new> HashMap();> > // Inserting the Elements> > // using put() method> > hm.put(> 1> ,> 'one'> );> > hm.put(> 2> ,> 'two'> );> > hm.put(> 3> ,> 'three'> );> > // Initialization of a Hashtable> > // using Generics> > Hashtable ht2> > => new> Hashtable(hm);> > // Print mappings to the console> > System.out.println(> 'Mappings of ht2 : '> + ht2);> > }> }> |
Výstup
Mappings of ht2 : {3=three, 2=two, 1=one} Příklad:
Jáva
// Java program to illustrate> // Java.util.Hashtable> import> java.util.*;> public> class> GFG {> > public> static> void> main(String[] args)> > {> > // Create an empty Hashtable> > Hashtable ht => new> Hashtable();> > // Add elements to the hashtable> > ht.put(> 'vishal'> ,> 10> );> > ht.put(> 'sachin'> ,> 30> );> > ht.put(> 'vaibhav'> ,> 20> );> > // Print size and content> > System.out.println(> 'Size of map is:- '> + ht.size());> > System.out.println(ht);> > // Check if a key is present and if> > // present, print value> > if> (ht.containsKey(> 'vishal'> )) {> > Integer a = ht.get(> 'vishal'> );> > System.out.println(> 'value for key'> > +> ' 'vishal' is:- '> + a);> > }> > }> }> |
Výstup
Size of map is:- 3 {vaibhav=20, vishal=10, sachin=30} value for key 'vishal' is:- 10 Provádění různých operací na Hashtable
1. Přidání prvků: K přidání prvku do hashtable můžeme použít metodu put(). Objednávka vložení však není v hashovací tabulce zachována. Interně je pro každý prvek vygenerován samostatný hash a prvky jsou indexovány na základě tohoto hashu, aby byl efektivnější.
Jáva
// Java program to demonstrate> // adding elements to Hashtable> import> java.io.*;> import> java.util.*;> class> AddElementsToHashtable {> > public> static> void> main(String args[])> > {> > // No need to mention the> > // Generic type twice> > Hashtable ht1 => new> Hashtable();> > // Initialization of a Hashtable> > // using Generics> > Hashtable ht2> > => new> Hashtable();> > // Inserting the Elements> > // using put() method> > ht1.put(> 1> ,> 'Geeks'> );> > ht1.put(> 2> ,> 'For'> );> > ht1.put(> 3> ,> 'Geeks'> );> > ht2.put(> 1> ,> 'Geeks'> );> > ht2.put(> 2> ,> 'For'> );> > ht2.put(> 3> ,> 'Geeks'> );> > > // Print mappings to the console> > System.out.println(> 'Mappings of ht1 : '> + ht1);> > System.out.println(> 'Mappings of ht2 : '> + ht2);> > }> }> |
Výstup
Mappings of ht1 : {3=Geeks, 2=For, 1=Geeks} Mappings of ht2 : {3=Geeks, 2=For, 1=Geeks} 2. Změna prvků: Po přidání prvků, pokud chceme prvek změnit, to lze provést opětovným přidáním prvku pomocí metody put(). Vzhledem k tomu, že prvky v hashovací tabulce jsou indexovány pomocí klíčů, hodnotu klíče lze změnit jednoduchým vložením aktualizované hodnoty klíče, který chceme změnit.
Jáva
// Java program to demonstrate> // updating Hashtable> import> java.io.*;> import> java.util.*;> class> UpdatesOnHashtable {> > public> static> void> main(String args[])> > {> > // Initialization of a Hashtable> > Hashtable ht> > => new> Hashtable();> > // Inserting the Elements> > // using put method> > ht.put(> 1> ,> 'Geeks'> );> > ht.put(> 2> ,> 'Geeks'> );> > ht.put(> 3> ,> 'Geeks'> );> > > // print initial map to the console> > System.out.println(> 'Initial Map '> + ht);> > > // Update the value at key 2> > ht.put(> 2> ,> 'For'> );> > > // print the updated map> > System.out.println(> 'Updated Map '> + ht);> > }> }> |
Výstup
Initial Map {3=Geeks, 2=Geeks, 1=Geeks} Updated Map {3=Geeks, 2=For, 1=Geeks} 3. Odebrání prvku: K odstranění prvku z mapy můžeme použít metodu remove(). Tato metoda převezme hodnotu klíče a odstraní mapování pro klíč z této mapy, pokud je v mapě přítomen.
Jáva
// Java program to demonstrate> // the removing mappings from Hashtable> import> java.io.*;> import> java.util.*;> class> RemovingMappingsFromHashtable {> > public> static> void> main(String args[])> > {> > // Initialization of a Hashtable> > Map ht> > => new> Hashtable();> > // Inserting the Elements> > // using put method> > ht.put(> 1> ,> 'Geeks'> );> > ht.put(> 2> ,> 'For'> );> > ht.put(> 3> ,> 'Geeks'> );> > ht.put(> 4> ,> 'For'> );> > // Initial HashMap> > System.out.println(> 'Initial map : '> + ht);> > // Remove the map entry with key 4> > ht.remove(> 4> );> > // Final Hashtable> > System.out.println(> 'Updated map : '> + ht);> > }> }> |
Výstup
Initial map : {4=For, 3=Geeks, 2=For, 1=Geeks} Updated map : {3=Geeks, 2=For, 1=Geeks} 4. Procházení hashtable: Pro iteraci tabulky můžeme použít pokročilé pro smyčku . Níže je uveden příklad iterace hashtable.
Jáva
// Java program to illustrate> // traversal of Hashtable> import> java.util.Hashtable;> import> java.util.Map;> public> class> IteratingHashtable {> > public> static> void> main(String[] args)> > {> > // Create an instance of Hashtable> > Hashtable ht => new> Hashtable();> > // Adding elements using put method> > ht.put(> 'vishal'> ,> 10> );> > ht.put(> 'sachin'> ,> 30> );> > ht.put(> 'vaibhav'> ,> 20> );> > > // Iterating using enhanced for loop> > for> (Map.Entry e : ht.entrySet())> > System.out.println(e.getKey() +> > + e.getValue());> > }> }> |
Výstup
vaibhav 20 vishal 10 sachin 30
Interní fungování Hashtable
Hashtable datová struktura je pole segmentů, které v nich ukládají páry klíč/hodnota. To využívá metoda hashCode(). určit, který segment by měl pár klíč/hodnota mapovat.
Hashovací funkce pomáhá určit umístění daného klíče v bucket listu. Obecně je hashcode nezáporné celé číslo, které je stejné pro stejné objekty a může nebo nemusí být stejné pro nestejné objekty. K určení, zda jsou dva objekty stejné nebo ne, používá hashtable metodu equals().
Je možné, že dva nestejné objekty mají stejný hashcode. Toto se nazývá a kolize . K vyřešení kolizí používá hashtable pole seznamů. Páry mapované do jednoho segmentu (index pole) jsou uloženy v seznamu a odkaz na seznam je uložen v indexu pole.
Metody hashtable
- K – Typ kláves na mapě.
- V – Typ hodnot mapovaných v mapě.
| METODA | POPIS |
|---|---|
| Průhledná() | Vymaže tuto hashovací tabulku, aby neobsahovala žádné klíče. |
| klon() | Vytvoří mělkou kopii této hashovací tabulky. |
| compute (klíč K, BiFunction K,? super V,? rozšiřuje V> remappingFunction) | Pokusí se vypočítat mapování pro zadaný klíč a jeho aktuální mapovanou hodnotu (nebo null, pokud neexistuje žádné aktuální mapování). |
| computeIfAbsent(klávesa K, funkce rozšiřuje V> mappingFunction) | Pokud zadaný klíč ještě není přidružen k hodnotě (nebo je mapován na hodnotu null), pokusí se vypočítat jeho hodnotu pomocí dané mapovací funkce a vloží ji do této mapy, pokud není null. |
| computeIfPresent (klávesa K, přemapování funkce BiFunction) | Pokud je hodnota pro zadaný klíč přítomna a není nulová, pokusí se vypočítat nové mapování dané klíčem a jeho aktuální mapovanou hodnotou. |
| obsahuje (hodnota objektu) | Testuje, zda se některý klíč mapuje na zadanou hodnotu v této hashovací tabulce. |
| obsahuje klíč (objektový klíč) | Testuje, zda je zadaný objekt klíčem v této hashovací tabulce. |
| obsahujeValue(hodnota objektu) | Vrátí hodnotu true, pokud tato hashovací tabulka mapuje jeden nebo více klíčů na tuto hodnotu. |
| Prvky() | Vrátí výčet hodnot v této hashovací tabulce. |
| entrySet() | Vrátí nastavení zobrazení mapování obsažených v této mapě. |
| rovná se (objekt o) | Porovná zadaný objekt s touto mapou pro dosažení rovnosti podle definice v rozhraní mapy. |
| get (klíč objektu) | Vrátí hodnotu, na kterou je zadaný klíč mapován, nebo hodnotu null, pokud tato mapa neobsahuje žádné mapování pro klíč. |
| hashCode() | Vrátí hodnotu hash kódu pro tuto mapu podle definice v rozhraní mapy. |
| je prázdný() | Testuje, zda tato hashovací tabulka nemapuje žádné klíče k hodnotám. |
| klíče() | Vrátí výčet klíčů v této hashovací tabulce. |
| keySet() | Vrátí zobrazení sady klíčů obsažených v této mapě. |
| sloučení (klíč K, hodnota V, přemapování funkce BiFunction) | Pokud zadaný klíč ještě není přidružen k hodnotě nebo je přidružen k hodnotě null, přidruží jej k dané jiné hodnotě. |
| put (klíč K, hodnota V) | Mapuje zadaný klíč na zadanou hodnotu v této hashovací tabulce. |
| putAll(mapa t) | Zkopíruje všechna mapování ze zadané mapy do této hashovací tabulky. |
| opakovat () | Zvyšuje kapacitu této hashovací tabulky a interně ji reorganizuje, aby bylo možné efektivněji pojmout její položky a přistupovat k nim. |
| odstranit (klíč objektu) | Odebere klíč (a jeho odpovídající hodnotu) z této hashovací tabulky. |
| velikost() | Vrátí počet klíčů v této hashovací tabulce. |
| toString() | Vrátí řetězcovou reprezentaci tohoto hashtable objektu ve formě sady položek uzavřených ve složených závorkách a oddělených znaky ASCII (čárka a mezera). |
| hodnoty() | Vrátí pohled kolekce hodnot obsažených v této mapě. |
Metody deklarované v rozhraní java.util.Map
| METODA | POPIS |
|---|---|
| pro každého (akce BiConsumer) | Provede danou akci pro každý záznam v této mapě, dokud nebudou zpracovány všechny záznamy nebo akce vyvolá výjimku. |
| getOrDefault (klíč objektu, V defaultValue) | Vrátí hodnotu, na kterou je zadaný klíč mapován, nebo defaultValue, pokud tato mapa neobsahuje žádné mapování pro klíč. |
| putIfAbsent(klíč K, hodnota V) | Pokud zadaný klíč ještě není přidružen k hodnotě (nebo je namapován na hodnotu null), přidruží jej k dané hodnotě a vrátí hodnotu null, jinak vrátí aktuální hodnotu. |
| odstranit (klíč objektu, Hodnota objektu) | Odebere položku pro zadaný klíč pouze v případě, že je aktuálně namapován na zadanou hodnotu. |
| nahradit (klíč K, hodnota V) | Nahradí položku pro zadaný klíč pouze v případě, že je aktuálně namapován na nějakou hodnotu. |
| nahradit (klíč K, V stará hodnota, V nová hodnota) | Nahradí položku pro zadaný klíč, pouze pokud je aktuálně namapován na zadanou hodnotu. |
| nahradit vše (funkce BiFunction) | Nahradí hodnotu každé položky výsledkem vyvolání dané funkce u této položky, dokud nebudou zpracovány všechny položky nebo funkce vyvolá výjimku. |
Musíš číst:
- Rozdíly mezi HashMap a HashTable v Javě
Výhody Hashtable:
- Thread-safe: Třída Hashtable je vlákno-safe, což znamená, že k ní může přistupovat více vláken současně, aniž by došlo k poškození dat nebo jiným problémům se synchronizací.
- Jednoduché použití: Třída Hashtable se snadno používá a poskytuje základní funkce datové struktury klíč-hodnota, což může být užitečné v jednoduchých případech.
Nevýhody Hashtable:
- Zastaralá: Třída Hashtable je považována za zastaralou a její používání se obecně nedoporučuje. Je to proto, že byl navržen před zavedením frameworku Collections a neimplementuje rozhraní Map, což ztěžuje použití ve spojení s jinými částmi frameworku.
- Omezená funkčnost: Třída Hashtable poskytuje základní funkce datové struktury klíč–hodnota, ale neposkytuje celou škálu funkcí, které jsou k dispozici v rozhraní Map a jeho implementacích.
- Špatný výkon: Třída Hashtable je synchronizovaná, což může mít za následek pomalejší výkon ve srovnání s jinými implementacemi rozhraní Map, jako je HashMap nebo ConcurrentHashMap.
Referenční knihy:
- Java Collections od Maurice Naftalina a Philipa Wadlera. Tato kniha poskytuje komplexní přehled o frameworku Java Collections, včetně třídy Hashtable.
- Java v kostce od Davida Flanagana. Tato kniha poskytuje rychlý odkaz na základní funkce Javy, včetně třídy Hashtable.
- Java Generics and Collections od Maurice Naftalina a Philipa Wadlera. Tato kniha poskytuje komplexního průvodce generikami a kolekcemi v Javě, včetně třídy Hashtable.
Odkaz: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Hashtable.html