🔥 🚀 Важно для всех, кто работает с Java! 🔥
На JavaRocks ты найдешь уникальные туториалы, практические задачи и редкие книги, которых не найти в свободном доступе. Присоединяйся к нашему Telegram-каналу JavaRocks — стань частью профессионального сообщества!
Если в Java-приложении нужно создать словарь, логичнее всего использовать соответствующую структуру данных, которая хранит пары «ключ — значение». В стандартной библиотеке есть специальный класс Dictionary
, а также его наследник — Hashtable
. Но чаще всего на практике применяются Map
и HashMap
, которые тоже работают с ключами и значениями. Таким образом, в Java существует несколько способов реализации словаря.
Структура данных Dictionary
Словарь (Dictionary) — это структура данных, которая хранит пары «ключ — значение».
Это означает, что к каждому значению привязывается определённый ключ (например, id), и эта пара добавляется в словарь. Все операции — обращение, поиск, удаление — происходят по ключу. Такой подход удобно использовать, например, при реализации телефонной книги, где в роли ключа выступает имя, а значением является номер телефона.
Класс Dictionary в Java и его расширения
Для начала стоит отметить, что java.util.Dictionary<K, V>
— это абстрактный класс. Он реализует принцип хранения данных в виде пар «ключ — значение». Используя ключ, вы можете сохранить значение, а затем получить его обратно по этому же ключу.
public abstract class Dictionary<K,V> extends Object
Run CodeПоскольку Dictionary
— абстрактный класс, напрямую его не используют. У него есть наследник — Hashtable
, и именно его можно применить для создания словаря в Java.
Hashtable
реализует хеш-таблицу, которая сопоставляет ключи и значения. В качестве ключа и значения можно использовать любые объекты, кроме null
.
В иерархии Java Hashtable
наследуется от Dictionary
и одновременно реализует интерфейс Map
.
Приведем пример. Создадим классический словарь — телефонную книгу — с использованием Hashtable
.
Dictionary phoneBook = new Hashtable();
Run CodeПри таком подходе для некоторых операций придётся использовать приведение типов. Например, чтобы получить ключ:
System.out.println(((Hashtable) phoneBook).keySet());
Run CodeЧтобы избежать этого, мы можем изменить
Dictionary phoneBook = new Hashtable ();
Run Codeна
Hashtable phoneBook = new Hashtable ();
Run CodeДля простоты и наглядности в примере оставим первый вариант.
import java.util.Dictionary;
import java.util.Hashtable;
public class DictionaryDemo {
public static void main(String[] args) {
Dictionary phoneBook = new Hashtable();
phoneBook.put("Johnny Walker", "2178");
phoneBook.put("Andrew Arnold", "1298");
phoneBook.put("Ivy Briggs", "1877");
phoneBook.put("Ricky McBright", "2001");
System.out.println(phoneBook);
System.out.println(phoneBook.get("Ivy Briggs"));
System.out.println(phoneBook.get("Sol Frank"));
System.out.println(((Hashtable) phoneBook).containsKey("Johnny Walker"));
System.out.println(((Hashtable) phoneBook).keySet());
System.out.println(((Hashtable) phoneBook).values());
System.out.println(phoneBook.size());
phoneBook.remove("Andrew Arnold");
System.out.println(phoneBook);
}
}
Run CodeВывод будет таким:
{Andrew Arnold=1298, Johnny Walker=2178, Ricky McBright=2001, Ivy Briggs=1877}
1877
null
true
[Andrew Arnold, Johnny Walker, Ricky McBright, Ivy Briggs]
[1298, 2178, 2001, 1877]
4
{Johnny Walker=2178, Ricky McBright=2001, Ivy Briggs=1877}
HashMap как альтернатива словарю
В отличие от Hashtable
, класс HashMap
не является прямым наследником Dictionary
. Из-за множества преимуществ, для создания словаря в большинстве случаев лучше использовать HashMap
. Классы HashMap
и Hashtable
схожи по функциональности, но есть важное отличие: методы в Hashtable
синхронизированы, а в HashMap
— нет. Из-за синхронизации в Hashtable
производительность падает. Кроме того, в отличие от Hashtable
, класс HashMap
позволяет использовать null
в качестве ключа (одного) и в качестве значений.
В нашем примере код будет практически таким же, как и выше — меняется только тип коллекции. Тем не менее, именно такой способ чаще всего рекомендуется для работы со словарями в Java.
import java.util.HashMap;
import java.util.Map;
public class DictionaryDemo2 {
public static void main(String[] args) {
Map<String, String> phoneBook = new HashMap<String,String>();
phoneBook.put("Johnny Walker", "2178");
phoneBook.put("Andrew Arnold", "1298");
phoneBook.put("Ivy Briggs", "1877");
phoneBook.put("Ricky McBright", "2001");
System.out.println(phoneBook);
System.out.println(phoneBook.get("Johnny Walker"));
System.out.println(phoneBook.get("Ivy Briggs"));
System.out.println(phoneBook.get("Unknown Friend"));
System.out.println(phoneBook.containsKey("Johnny Walker"));
System.out.println(phoneBook.containsKey("Unknown Friend"));
System.out.println(phoneBook.keySet());
System.out.println(phoneBook.values());
System.out.println(phoneBook.size());
phoneBook.remove("Andrew Arnold");
System.out.println(phoneBook);
}
}
Run CodeВот что выведет программа:
{Andrew Arnold=1298, Ivy Briggs=1877, Ricky McBright=2001, Johnny Walker=2178}
2178
1877
null
true
false
[Andrew Arnold, Ivy Briggs, Ricky McBright, Johnny Walker]
[1298, 1877, 2001, 2178]
4
{Ivy Briggs=1877, Ricky McBright=2001, Johnny Walker=2178}
Класс Dictionary
был частью Java с самого начала — он использовался как хранилище пар ключ-значение. Однако в современной практике его использование не рекомендуется из-за ряда ограничений и наличия более удобных альтернатив. В этом материале разберём, почему Dictionary
больше не актуален и чем его стоит заменить.
Почему Dictionary больше не используют
В актуальной Java Dictionary
считается устаревшим. Он появился ещё в Java 1.0, но с тех пор его вытеснили более гибкие и мощные инструменты — например, интерфейс Map
и такие его реализации, как HashMap
и TreeMap
. Вот основные причины отказа от Dictionary
:
- Отсутствие обновлений:
Dictionary
не обновлялся и не поддерживает новые фичи, появившиеся в последних версиях Java. - Заменён интерфейсом Map: Интерфейс
Map
— это современный, удобный и гибкий способ работать с ключами и значениями. - Устаревший стиль: Стиль
Dictionary
устарел — он не совместим с системой дженериков, введённой в Java 5.
Ограниченная функциональность класса Dictionary
По сравнению с интерфейсом Map
и его реализациями, класс Dictionary
обладает рядом функциональных ограничений:
- Отсутствие поддержки итераций: В
Dictionary
отсутствуют встроенные средства для перебора ключей и значений, что затрудняет его использование. - Нельзя использовать null: В отличие от
HashMap
, классDictionary
не допускаетnull
в качестве ключей или значений. - Ограниченный API:
Dictionary
предлагает лишь базовые методы —put()
,get()
,remove()
, тогда какMap
предоставляет гораздо более широкий набор возможностей: получение множеств ключей, коллекций значений, расширенные операции и прочее.
Пример использования API класса Dictionary:
import java.util.Dictionary;
import java.util.Hashtable;
public class DictionaryExample {
public static void main(String[] args) {
Dictionary dictionary = new Hashtable<>();
dictionary.put("key1", "value1");
dictionary.put("key2", "value2");
System.out.println("Value for key1: " + dictionary.get("key1"));
}
}
Run CodeХотя этот пример демонстрирует базовое использование, ограниченность API становится очевидной при сравнении с интерфейсом Map
.
Отсутствие типобезопасности в Dictionary
Класс Dictionary
не поддерживает обобщения (generics), что может привести к проблемам с безопасностью типов. Например:
import java.util.Dictionary;
import java.util.Hashtable;
public class TypeSafetyExample {
public static void main(String[] args) {
Dictionary dictionary = new Hashtable();
dictionary.put("key1", "value1");
dictionary.put(42, "value2");
String value = (String) dictionary.get(42);
}
}
Run CodeВывод программы:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Чтобы минимизировать такие риски, современные программы на Java должны работать с интерфейсом Map
, который поддерживает дженерики и гарантирует безопасность типов:
import java.util.Map;
import java.util.HashMap;
public class TypeSafeExample {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
String value = map.get("key1");
System.out.println("Value: " + value);
}
}
Run CodeПеревод статьи «How to create a dictionary in Java».