logo

Хеш-таблиця в 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



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

>

>

Вихід

Команда повернення java
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:

  1. Потокобезпечний: клас Hashtable є потокобезпечним, тобто кілька потоків можуть отримати доступ до нього одночасно, не спричиняючи пошкодження даних чи інших проблем із синхронізацією.
  2. Простий у використанні: Клас Hashtable простий у використанні та надає основні функції структури даних типу 'ключ-значення', що може бути корисним у простих випадках.

Недоліки Hashtable:

  1. Застарілий: Клас Hashtable вважається застарілим, і його використання, як правило, не рекомендується. Це пов’язано з тим, що він був розроблений до впровадження фреймворку Collections і не реалізує інтерфейс Map, що ускладнює його використання в поєднанні з іншими частинами фреймворку.
  2. Обмежена функціональність: клас Hashtable надає основні функції структури даних 'ключ-значення', але не надає повного спектру функцій, доступних в інтерфейсі карти та його реалізаціях.
  3. Низька продуктивність: клас Hashtable синхронізовано, що може призвести до нижчої продуктивності порівняно з іншими реалізаціями інтерфейсу Map, такими як HashMap або ConcurrentHashMap.

Довідники:

  1. Колекції Java від Моріса Нафталіна та Філіпа Уодлера. У цій книзі представлено вичерпний огляд структури Java Collections, включаючи клас Hashtable.
  2. Java in Nutshell Девід Фланаган. У цій книзі наведено короткий довідник про основні функції Java, включаючи клас Hashtable.
  3. 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