Хеш-таблиця в Java
The Хеш-таблиця клас реалізує хеш-таблицю, яка відображає ключі на значення. Будь-який ненульовий об’єкт можна використовувати як ключ або як значення. Щоб успішно зберігати й отримувати об’єкти з хеш-таблиці, об’єкти, які використовуються як ключі, мають реалізовувати метод hashCode і метод equals.
Клас java.util.Hashtable — це клас у Java, який надає структуру даних «ключ-значення», подібну до інтерфейсу Map. Він був частиною оригінальної структури Java Collections і був представлений у Java 1.0.
Однак клас Hashtable з тих пір вважається застарілим, і його використання, як правило, не рекомендується. Це пов’язано з тим, що він був розроблений до впровадження фреймворку Collections і не реалізує інтерфейс Map, що ускладнює його використання в поєднанні з іншими частинами фреймворку. Крім того, клас Hashtable синхронізовано, що може призвести до зниження продуктивності порівняно з іншими реалізаціями інтерфейсу Map.
Загалом, рекомендується використовувати інтерфейс Map або одну з його реалізацій (наприклад, HashMap або ConcurrentHashMap) замість класу Hashtable.
Ось приклад використання класу Hashtable:
Java
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));> > }> > }> }> |
Вихід
Value of A: 1 Key: A, Value: 1 Key: C, Value: 3
Підсумовуючи, хоча клас Hashtable все ще існує в Java і все ще може використовуватися, зазвичай рекомендується використовувати інтерфейс Map або одну з його реалізацій.
Особливості Hashtable
- Він схожий на HashMap, але синхронізований.
- Hashtable зберігає пару ключ/значення в хеш-таблиці.
- У Hashtable ми вказуємо об’єкт, який використовується як ключ, і значення, яке ми хочемо пов’язати з цим ключем. Потім ключ хешується, а отриманий хеш-код використовується як індекс, за яким значення зберігається в таблиці.
- Початкова ємність класу Hashtable за замовчуванням становить 11, тоді як loadFactor становить 0,75.
- HashMap не забезпечує перерахування, тоді як Hashtable не забезпечує швидкого перерахування.
Декларація:
public class Hashtable extends Dictionary implements Map, Cloneable, Serializable
Параметри типу:
- К – тип ключів, які підтримує ця карта
- IN – тип відображених значень
Ієрархія хеш-таблиці
Реалізує хеш-таблицю Серіалізований , Можливість клонування , Карта інтерфейси та розширення Словник . Прямими підкласами є властивості, UI за замовчуванням .
Конструктори:
Щоб створити хеш-таблицю, нам потрібно імпортувати її з java.util.Hashtable . Існують різні способи створення хеш-таблиці.
1. Хеш-таблиця(): Це створює порожню хеш-таблицю з коефіцієнтом завантаження за замовчуванням 0,75 і початковою ємністю 11.
Хеш-таблиця ht = нова хеш-таблиця();
Java
// 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);> > }> }> |
Вихід
Mappings of ht1 : {3=three, 2=two, 1=one} Mappings of ht2 : {6=six, 5=five, 4=four} 2. Хеш-таблиця (int initialCapacity): Це створює хеш-таблицю з початковим розміром, визначеним initialCapacity, і коефіцієнтом завантаження за замовчуванням 0,75.
Hashtable ht = нова Hashtable(int initialCapacity);
Java
// 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);> > }> }> |
Вихід
Mappings of ht1 : {3=three, 2=two, 1=one} Mappings of ht2 : {4=four, 6=six, 5=five} 3. Хеш-таблиця (int size, float fillRatio): Ця версія створює хеш-таблицю, яка має початковий розмір, визначений розміром, і коефіцієнт заповнення, визначений fillRatio. Коефіцієнт заповнення: по суті, він визначає, наскільки заповненою може бути хеш-таблиця до того, як її розмір буде змінено вгору, а її значення буде від 0,0 до 1,0.
Хеш-таблиця ht = нова хеш-таблиця (int size, float fillRatio);
Java
// 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);> > }> }> |
Вихід
Mappings of ht1 : {3=three, 2=two, 1=one} Mappings of ht2 : {6=six, 5=five, 4=four} 4. Хеш-таблиця (Карта m): Це створює хеш-таблицю, яка ініціалізується елементами в m.
Hashtable ht = нова Hashtable(Map m);
Java
// 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);> > }> }> |
Вихід
Mappings of ht2 : {3=three, 2=two, 1=one} приклад:
Java
// 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);> > }> > }> }> |
Вихід
Size of map is:- 3 {vaibhav=20, vishal=10, sachin=30} value for key 'vishal' is:- 10 Виконання різноманітних операцій над Hashtable
1. Додавання елементів: Щоб додати елемент до хеш-таблиці, ми можемо використати метод put(). Однак порядок вставки не зберігається в хеш-таблиці. Внутрішньо для кожного елемента генерується окремий хеш, і елементи індексуються на основі цього хешу, щоб зробити його більш ефективним.
Java
// 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);> > }> }> |
Вихід
Mappings of ht1 : {3=Geeks, 2=For, 1=Geeks} Mappings of ht2 : {3=Geeks, 2=For, 1=Geeks} 2. Зміна елементів: Після додавання елементів, якщо ми хочемо змінити елемент, це можна зробити, знову додавши елемент за допомогою методу put(). Оскільки елементи в хеш-таблиці індексуються за допомогою ключів, значення ключа можна змінити, просто вставивши оновлене значення для ключа, для якого ми хочемо змінити.
Java
// 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);> > }> }> |
Вихід
Initial Map {3=Geeks, 2=Geeks, 1=Geeks} Updated Map {3=Geeks, 2=For, 1=Geeks} 3. Видалення елемента: Щоб видалити елемент із карти, ми можемо використати метод remove(). Цей метод приймає значення ключа та видаляє відображення для ключа з цієї карти, якщо він присутній у карті.
Java
// 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);> > }> }> |
Вихід
Initial map : {4=For, 3=Geeks, 2=For, 1=Geeks} Updated map : {3=Geeks, 2=For, 1=Geeks} 4. Обхід хеш-таблиці: Для ітерації таблиці ми можемо використати an розширений цикл for . Нижче наведено приклад ітерації хеш-таблиці.
Java
// 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());> > }> }> |
Вихід
vaibhav 20 vishal 10 sachin 30
Внутрішня робота хеш-таблиці
Структура даних хеш-таблиці — це масив сегментів, у якому зберігаються пари ключ/значення. Це використовує метод hashCode(). щоб визначити, яке відро має зіставлятися пара ключ/значення.
Хеш-функція допомагає визначити розташування даного ключа в списку сегментів. Загалом хеш-код — це невід’ємне ціле число, яке є рівним для однакових об’єктів і може бути або не бути рівним для нерівних об’єктів. Щоб визначити рівність двох об’єктів, хеш-таблиця використовує метод equals().
Можливо, що два нерівних об’єкти мають однаковий хеш-код. Це називається a зіткнення . Для вирішення колізій хеш-таблиця використовує масив списків. Пари, зіставлені в одне відро (індекс масиву), зберігаються в списку, а посилання на список зберігається в індексі масиву.
Методи Hashtable
- К – Тип ключів на карті.
- IN – Тип значень, відображених на карті.
| МЕТОД | ОПИС |
|---|---|
| очистити() | Очищає цю хеш-таблицю, щоб вона не містила ключів. |
| клонувати() | Створює поверхневу копію цієї хеш-таблиці. |
| compute(клавіша K, BiFunction К,? супер V,? розширює V> remappingFunction) | Намагається обчислити відображення для вказаного ключа та його поточного відображеного значення (або значення null, якщо поточного відображення немає). |
| computeIfAbsent(клавіша K, функція розширює V> mappingFunction) | Якщо вказаний ключ ще не пов’язано зі значенням (або зіставлено з null), намагається обчислити його значення за допомогою заданої функції відображення та вводить його в цю карту, якщо він не null. |
| computeIfPresent(клавіша K, BiFunction remappingFunction) | Якщо значення для вказаного ключа присутнє та відмінне від null, намагається обчислити нове зіставлення з урахуванням ключа та його поточного зіставленого значення. |
| містить (значення об'єкта) | Перевіряє, чи співпадає якийсь ключ із вказаним значенням у цій хеш-таблиці. |
| містить ключ (ключ об'єкта) | Перевіряє, чи є вказаний об’єкт ключем у цій хеш-таблиці. |
| containsValue(значення об'єкта) | Повертає true, якщо ця хеш-таблиця зіставляє один або кілька ключів із цим значенням. |
| елементи () | Повертає перелік значень у цій хеш-таблиці. |
| entrySet() | Повертає представлення набору відображень, які містяться на цій карті. |
| дорівнює (об'єкт o) | Порівнює вказаний об’єкт із цією картою на рівність, згідно з визначенням в інтерфейсі карти. |
| отримати (ключ об'єкта) | Повертає значення, на яке зіставляється вказаний ключ, або null, якщо ця карта не містить зіставлення для ключа. |
| hashCode() | Повертає значення хеш-коду для цієї карти відповідно до визначення в інтерфейсі карти. |
| пусто() | Перевіряє, чи не зіставляє ця хеш-таблиця ключі зі значеннями. |
| ключі() | Повертає перелік ключів у цій хеш-таблиці. |
| keySet() | Повертає набір перегляду ключів, які містяться на цій карті. |
| merge (ключ K, значення V, функція перевідображення BiFunction) | Якщо вказаний ключ ще не пов’язано зі значенням або пов’язано з null, пов’язує його з заданим ненульовим значенням. |
| поставити (ключ K, значення V) | Зіставляє вказаний ключ із вказаним значенням у цій хеш-таблиці. |
| putAll(Map t) | Копіює всі зіставлення з указаної карти в цю хеш-таблицю. |
| rehash() | Збільшує місткість і внутрішню реорганізацію цієї хеш-таблиці для більш ефективного розміщення та доступу до її записів. |
| видалити (ключ об'єкта) | Вилучає ключ (і його відповідне значення) із цієї хеш-таблиці. |
| розмір() | Повертає кількість ключів у цій хеш-таблиці. |
| toString() | Повертає рядкове представлення цього об’єкта Hashtable у вигляді набору записів, укладених у фігурні дужки та розділених символами ASCII (кома та пробіл). |
| значення() | Повертає перегляд колекції значень, які містяться на цій карті. |
Методи, оголошені в інтерфейсі java.util.Map
| МЕТОД | ОПИС |
|---|---|
| forEach(дія BiConsumer) | Виконує вказану дію для кожного запису в цій карті, доки всі записи не будуть оброблені або дія не викличе виняток. |
| getOrDefault(ключ об'єкта, V defaultValue) | Повертає значення, на яке зіставляється вказаний ключ, або defaultValue, якщо ця карта не містить зіставлення для ключа. |
| putIfAbsent (ключ K, значення V) | Якщо вказаний ключ ще не пов’язано зі значенням (або зіставлено з null), він пов’язує його з заданим значенням і повертає null, інакше повертає поточне значення. |
| видалити (ключ об'єкта, Значення об'єкта) | Видаляє запис для вказаного ключа, лише якщо він наразі зіставлений із вказаним значенням. |
| замінити (клавіша K, значення V) | Замінює запис для вказаного ключа, лише якщо він наразі зіставлено з деяким значенням. |
| замінити (ключ K, V oldValue, V newValue) | Замінює запис для вказаного ключа, лише якщо наразі зіставлено з вказаним значенням. |
| replaceAll (функція BiFunction) | Замінює значення кожного запису результатом виклику даної функції для цього запису, доки всі записи не будуть оброблені або функція викличе виняткову ситуацію. |
Необхідно прочитати:
- Відмінності між HashMap і HashTable в Java
Переваги Hashtable:
- Потокобезпечний: клас Hashtable є потокобезпечним, тобто кілька потоків можуть отримати доступ до нього одночасно, не спричиняючи пошкодження даних чи інших проблем із синхронізацією.
- Простий у використанні: Клас Hashtable простий у використанні та надає основні функції структури даних типу 'ключ-значення', що може бути корисним у простих випадках.
Недоліки Hashtable:
- Застарілий: Клас Hashtable вважається застарілим, і його використання, як правило, не рекомендується. Це пов’язано з тим, що він був розроблений до впровадження фреймворку Collections і не реалізує інтерфейс Map, що ускладнює його використання в поєднанні з іншими частинами фреймворку.
- Обмежена функціональність: клас Hashtable надає основні функції структури даних 'ключ-значення', але не надає повного спектру функцій, доступних в інтерфейсі карти та його реалізаціях.
- Низька продуктивність: клас Hashtable синхронізовано, що може призвести до нижчої продуктивності порівняно з іншими реалізаціями інтерфейсу Map, такими як HashMap або ConcurrentHashMap.
Довідники:
- Колекції Java від Моріса Нафталіна та Філіпа Уодлера. У цій книзі представлено вичерпний огляд структури Java Collections, включаючи клас Hashtable.
- Java in Nutshell Девід Фланаган. У цій книзі наведено короткий довідник про основні функції Java, включаючи клас Hashtable.
- Java Generics and Collections by Maurice Naftalin і Philip Wadler. У цій книзі міститься вичерпний посібник із генериків і колекцій у Java, включаючи клас Hashtable.
Посилання: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Hashtable.html