JavaRush /Курсы /Java Syntax Pro /Знакомство с коллекцией HashMap

Знакомство с коллекцией HashMap

Java Syntax Pro
13 уровень , 3 лекция
Открыта

1. Множество пар: ключ-значение.

Множество пар: ключ-значение

В Java есть еще одна интересная коллекция (в широком смысле) — это коллекция Map. Точного перевода ее названия на русский нет: чаще всего ее называют «карта», «словарь» или просто «мапа».

Эта коллекция похожа на коллекцию Set, только хранит не множество элементов, а множество «пар элементов». Каждая пара элементов Map состоит из двух: «ключ» и «значение».

Допустим, вы хотите хранить в программе имена сотрудников компании, их зарплаты или имена ваших коллег и их возраст. Тогда вам бы понадобилась таблица типа такой:

Имя Возраст
Сергей 21
Николай 22
Иван Петрович 48
Анюта ?

В каждой строке тут хранится пара величин. Имя мы будем называть ключом пары, а возраст — значением пары.

Весь набор таких пар и будет называться картойMap.

Ключом пары может быть что угодно, но у некоторых типов карт ключ не может быть null. Ключи должны быть уникальные: одна карта не может содержать два одинаковых ключа.


2. Класс HashMap

Класс HashMap является самой популярной коллекцией из всех карт (Map). С одной стороны, он очень похож на HashSet и имеет все его методы, а с другой — на список (ArrayList), если бы индексами у списка могли быть не числа, а слова.

Создать объект типа HashMap можно с помощью команды вида:

HashMap<TКлюч, TЗначение> имя = new HashMap<TКлюч, TЗначение>();

Где TКлюч — это тип ключей из пары элементов, TЗначение — тип значений в паре элементов, которые будут храниться в коллекции HashMap.

У класса HashMap есть такие методы:

Метод Описание
void put(ТКлюч key, ТЗначение value)
Добавляет в коллекцию пару (key, value)
ТЗначение get(ТКлюч key)
Возвращает значение по ключу.
boolean containsKey(ТКлюч key)
Проверяет наличие ключа в коллекции
boolean containsValue(ТЗначение value)
Проверяет наличие значения в коллекции
ТЗначение remove(ТКлюч key)
Удаляет элемент из коллекции
void clear()
Очищает коллекцию: удаляет все элементы
int size()
Возвращает количество пар элементов в коллекции
Set<ТКлюч> keySet()
Возвращает множество ключей коллекции
Collection<ТЗначение> values()
Возвращает множество элементов коллекции
Set<Map.Entry<TКлюч, TЗначение>> entrySet()
Возвращает все значения коллекции в виде множества (Set) пар (Map.Entry).

Добавление элементов в HashMap

Элементы добавляются в карту сразу парами: для этого используется метод put(). Первым в него передается ключ, вторым — значение.

HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Серега", 21);
map.put("Николай", 22);
map.put("Иван Петрович", 48);
map.put("Анюта", null);

Если при добавлении элемента выяснится, что элемент с таким ключом уже есть, старое значение ключа заменится на новое.

Такое поведение делает HashMap похожим на массив или список, если бы у них в качестве индексов выступали слова (String), а не числа.

Важно:

В качестве Типа-Ключа и Типа-Значения могут выступать практически любые типы. Есть небольшие дополнительные требования к Типу-Ключу, но о них вы узнаете при детальном изучении коллекций в квесте Java Collections.



3. Подмножества HashMap: множество ключей

Допустим мы хотим просто вывести все элементы HashMap на экран, как нам это сделать? Для этого нужно понять, как пройтись по всем элементам HashMap. Это можно сделать разными способами.

Самый простой способ – использовать цикл по ключам

У элементов класса HashMap нет порядкового номера, поэтому цикл со счетчиком тут не подойдет. Зато мы можем получить множество ключей с помощью метода keySet(), а как пройтись по множеству вы уже знаете:

Код Описание
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Серега", 21);
map.put("Николай", 22);
map.put("Иван Петрович", 48);
map.put("Анюта", null);

for (String key: map.keySet())
{
   Integer value = map.get(key);
   System.out.println(key + " --> " + value);
}






Цикл по всем ключам map

Получаем значение по ключу

Метод keySet() возвращает множество ключей. Можно использовать это множество двумя способами:

Компактная запись Длинная запись
for (String key: map.keySet())
{
   Integer value = map.get(key);
   System.out.println(key + " --> " + value);
}
Set<String> keys = map.keySet();

for (String key: keys)
{
   Integer value = map.get(key);
   System.out.println(key + " --> " + value);
}


4. Использование цикла по парам

Есть и более сложный способ: можно преобразовать Map в множество пар элементов, а потом использовать цикл по элементам множества, как мы уже раньше учили.

В коллекции HashMap есть вспомогательный класс для хранения пары элементов. Выглядит он примерно так:

class Entry<KeyType, ValueType>
{
   private KeyType key;
   private ValueType value;

   public KeyType getKey()
   {
      return this.key;
   }

   public ValueType getValue()
   {
      return this.value;
   }
}

Результат вызова метода entrySet() у объекта типа HashMap<ТКлюч, ТЗначение> будет иметь тип Set<Entry<ТКлюч, ТЗначение>>:

Set<Entry<Ключ, Значение>> имя = map.entrySet();

Тут мы видим сложный тип Set с параметром-значением, а в качестве параметра-значение выступает еще один сложный тип (Entry), так еще и с двумя параметрами.

Новичку очень легко в этом запутаться. Хотя, если разберетесь, сможете писать код вида:

HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Серега", 21);
map.put("Николай", 22);
map.put("Иван Петрович", 48);
map.put("Анюта", null);

Set<Map.Entry<String, Integer>> entries = map.entrySet();
for(Map.Entry<String, Integer> pair: entries)
{
   String key = pair.getKey();
   Integer value = pair.getValue();
   System.out.println(key + " --> " + value);
}

Хотя этот код можно и немножко упростить:

Во-первых, можно не создавать отдельную переменную для entries, а сразу вызвать метод entrySet() внутри цикла for:

for(Map.Entry<String, Integer> pair: map.entrySet())
{
   String key = pair.getKey();
   Integer value = pair.getValue();
   System.out.println(key + " --> " + value);
}

Во-вторых, можно воспользоваться недавно появившимся оператором var для автоматического выведения типа пары элементов:

for(var pair: map.entrySet())
{
   String key = pair.getKey();
   Integer value = pair.getValue();
   System.out.println(key + " --> " + value);
}

Уже неплохо, да?



5. Сравнение ArrayList vs HashMap

HashMap сильно напоминает ArrayList, у которого в качестве индексов используются не цифры, а слова (или другой тип ключей).

А если в качестве ключа в HashMap использовать Integer, он становится еще более похожим на ArrayList. Сравните:

Код с ArrayList<String> Код с HashMap<Integer, String>
ArrayList<String> list = new ArrayList<String>();

list.add("Привет");
list.add("Hello");

String s = list.get(0);
list.set(0, s + "!");

for (String item: list)
{
   System.out.println(item);
}
HashMap<Integer, String> map = new HashMap<Integer, String>();

map.put(0, "Привет");
map.put(1, "Hello");

String s = map.get(0);
map.put(0, s + "!");

for (String item: map.values())
{
   System.out.println(item);
}

Комментарии (382)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Lena Уровень 14
5 марта 2026
Метод values() возвращает коллекцию, состоящую исключительно из Значений вдруг кого тоже сбила с толку такая формулировка в теории

Collection<ТЗначение> values()
Возвращает множество элементов коллекции
Grigoryvvv Уровень 15 Expert
5 февраля 2026
16.02.2026 / 14 уровень ● Схема реализация коллекций Map в Java Map (интерфейс) ├── put(K key, V value) ├── get(K key) ├── entrySet() ├── ... └── Entry (вложенный интерфейс) ├── getKey() ├── getValue() └── ... HashMap (класс) ──implements──> Map ├── put(K key, V value) { ... } ├── get(K key) { ... } ├── entrySet() { ... } // возвращает Set<Map.Entry<K,V>> ├── ... └── Node (вложенный static class) ──implements──> Map.Entry ├── getKey() { ... } ├── getValue() { ... } ├── setValue(V value) { ... } └── ... TreeMap (класс) ──implements──> Map ├── ... ... LinkedHashMap (класс) ──extends──> HashMap ├── ... ... Мы имеем общий для классов HashMap, TreeMap, LinkedHashMap, интерфейс Map с вложенным в него интерфейсом Entry. В JDK:

public interface Map<K,V> {
    Set<Map.Entry<K,V>> entrySet(); 
    …
    interface Entry<K,V> {
        K getKey();
        V getValue();
        V setValue(V value);
        …
    }
}
Классы HashMap, TreeMap, LinkedHashMap имеют каждый свою конкретную реализацию интерфейса Map и вложенного в него интерфейса Entry

class HashMap<K,V> implements Map<K,V> {
    Set<Map.Entry<K,V>> entrySet() { ... }    // возвращает Set<Map.Entry<K,V>>

    static class Node<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Node<K,V> next;

        public K getKey() { return key; }
        public V getValue() { return value; }
        public V setValue(V value) { ... }
    }
}
Grigoryvvv Уровень 15 Expert
5 февраля 2026
Таким образом Entry это не класс, а вложенный интерфейс в интерфейс Map. Класс HashMap<K,V> implements (реализует) интерфейс Map<K,V>, со своей реализацией метода entrySet(). Вложенный в класс HashMap статический класс Node implements (реализует) вложенный в интерфейс Map интерфейс Entry, со своей реализацией методов getKey(), getValue(), setValue()... ● Разберем подробно строку

Set<Map.Entry<String, Integer>> entries = map.entrySet();
Из 4 лекции 12 уровня под названием "Статические классы (static class) в Java" мы знаем, для обращения к вложенным или внутренним классам не из его класса-родителя, а из другого места в программе, нужно будет указать имя класса: оно состоит из имени класса родителя и имени вложенного класса. Общий вид имени:

ИнтерфейсРодитель.Вложенныйинтерфейс
или
КлассРодитель.ВложенныйКласс

Map.Entry<String, Integer>
или
HashMap.Node<String, Integer>
Так как метод entrySet() возвращает все значения в виде множества (Set) пар класса (HashMap.Node) выполнив восходящее преобразование типа ссылочной переменной объекта класса до типа интерфейса (Map.Entry)

Set<Map.Entry<String, Integer>> entries = map.entrySet();
мы можем работать с объектами классов HashMap, TreeMap, LinkedHashMap, не переписывая код в левой части (полиморфизм). Это такое же восходящее преобразование типа ссылочной переменной объекта класса до типа интерфейса, как и в примере:

List<String> list = new ArrayList<>();
HashMap (хеш-карта) — не является коллекцией (Collection) в строгой форме, но входит в состав Java Collections Framework. Коллекции это: строго → только Collection разговорно → всё из JСF
Роман Уровень 32
7 января 2026
Вот с чего везде add, а тут сцукко, put?
Anonymous #3558991 Уровень 15
13 января 2026
Потому что метод add используется у ArrayList. А у Map используется put чтобы добавить что-то в коллекцию. Это всегда так ,просто запомни
Bohdan Уровень 10
21 января 2026
Если коротко, то дело в сути методов добавления. Если в ArrayList мы просто добавляем (add), то в HashSet мы как бы кладём пару, и если вдруг пара с тем же ключом уже есть, она заменяется новой, то есть это уже не совсем добавление. Поэтому и метод имеет другое название
Роман Уровень 32
24 января 2026
Спасибо, понятно пояснил🤝
Underdante Уровень 19
1 марта 2026
тогда вопрос. почему в set который по сути своеи map , но без значении, мы пишем add???
C0N5P1RACY Уровень 41
21 декабря 2025
Не знаю почему, но эта тема оказалась для меня довольно сложной... Я часа полтора пытался разобраться как работает этот HashMap, конечно, по сути, когда уже разобрался, оказалось все проще чем я думал, но конспект в моем обсидиан получился очень длинный... Когда разбираешься, кажется что это ппц тяжело, а когда уже разобрался, кажется что это все элементарно. Могу сказать очень коротко: HashMap это как таблица, как телефонная книга, где вместо индексов у нас какие то значения. Условно Серега -> +7 900 100 20 30 Олег -> +1 234 567 89 00 Самара -> 8 800 555 35 35 Имена это ключи (ключом может быть что угодно) Номера телефонов это значения. Значения привязаны к ключам, как и наоборот, мы можем получить значение по ключу (и наоборот тоже) Это как эксель таблица
Daria #3614631 Уровень 16
17 ноября 2025
Топ моих ошибок на курсе: не поставить пробел, забыть ; или } .когда вижу ошибку в задаче - чаще всего сразу понимаю, что опять пошло не так..
Anonymous #3569694 Уровень 22
6 сентября 2025
пункт 4 он вообще про что??? я ничего не могу понять. с одной формулы на другую прыгаете, а смысл не объясняете зачем это нужно и когда применять
invoker main Уровень 42
19 сентября 2025
Когда лень полностью расписывать, это чтобы ты понял, как работает и че пишет там
7 октября 2025
Пары ключ-значение хранятся в полях внутреннего класса. Видимо, это класс Entry. За пределами внешнего класса (Map), он пишется как Map.Entry. Класс Entry (Map.Entry) типизированный: у него есть два параметра-типа. При объявлении переменной Map.Entry нужно указать также эти типы в угловых скобках. Да, тип переменной получится очень длинным. Поэтому,предлагается заменить его на слово var. Объекты Map.Entry можно получить с помощью метода entrySet(). Он возврщает Set этих объектов. У класса Map.Entry есть приватные поля key и value, а также публичные геттеры. С помощью геттеров можно получить значение поля key или поля value. Вообще, все коллекции основаны на использовании либо массива и внутренних дата классов, либо только на внутренних дата-классах. Дата классы нужны для хранения данных в своих полях.
Grigoryvvv Уровень 15 Expert
14 февраля 2026
Map и Entry не классы. Map это интерфейс, а Entry это вложенный интерфейс в Map.
Anonymous #3569694 Уровень 22
6 сентября 2025
такое ощущение что вы для себя лекции пишете
Alexander Pavlyuchenko Уровень 28
31 июля 2025
Что-то очень похожее проходил именно с коллекцией до этого, именно с HashMap кто нибудь знает на каком уровне, лекции можно почитать? Помню приводили примеры с к ключом. Например по номеру паспорта (уникальному ключу) можно найти ФИО, возраст и т.д. Хотелось бы вспомнить освежить в голове. Заранее спасибо!
Anonymous #3585174 Уровень 33
5 июля 2025
Like
Виктор Уровень 26
14 июня 2025
Материал дае́тся хорошо, но чувствую что забудется без повторения и практики.
Georgy Dmitriev Уровень 19
31 июля 2025
ой там практики еще гора где можно применить такой подход, ты не обязан решать множество задач тривиально -> знаешь применяй даже если тема не требует мамы