JavaRush/Курси/Java Syntax Zero/Знайомство з колекцією HashMap

Знайомство з колекцією HashMap

Відкрита

1. Множина пар: ключ–значення

>

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

Ця колекція схожа на колекцію Set, але зберігає не множину елементів, а множину «пар елементів». Кожна пара елементів Map — це «ключ» і «значення».

Припустімо, ви хочете зберігати в програмі імена працівників компанії та їхні зарплати або імена своїх колег та їхній вік. Тоді вам знадобиться така таблиця:

Ім'я Вік
Сергій 21
Микола 22
Іван Петрович 48
Ганнуся ?

Тут у кожному рядку зберігається пара значень. Ім'я будемо називати ключем пари, а вік — значенням пари.

Увесь набір таких пар і буде називатися мапою — Map.

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


2. Клас HashMap

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

Створити об'єкт типу HashMap можна за допомогою такої команди:

HashMap<TКлюч, TЗначення> ім'я = new HashMap<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.


14
Задача
Java Syntax Zero,  14 рівень,  4 лекція
Недоступна
Успішність студентів
Успішність студентів

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

14
Задача
Java Syntax Zero,  14 рівень,  4 лекція
Недоступна
Успішність студентів-2
Успішність студентів-2

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

Непогано, чи не так?


14
Задача
Java Syntax Zero,  14 рівень,  4 лекція
Недоступна
Успішність студентів-3
Успішність студентів-3

5. Порівняння ArrayList і 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);
}

14
Задача
Java Syntax Zero,  14 рівень,  4 лекція
Недоступна
ArrayList і HashMap
ArrayList і HashMap
Коментарі (16)
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
Soros
Рівень 25
27 серпня 2025, 14:32
Методу void put(ТКлюч key, ТЗначення value) у класі HashMap немає! Існує метод V put(ТКлюч key, ТЗначення value) - тобто цей метод повертає або null в тому випадку, коли такого ключа ще не додавалось, або ТЗначення value, якщо така сама пара вже існує в HashMap об'єкті
Михайло
Рівень 117
8 січня 2025, 12:45
3 задача тупо копіпаста з лекції)
Кирило
Рівень 43
19 липня 2024, 11:01
Шось я завис на успішності студентів-2
Ivan Maksymovych
Рівень 1
Expert
5 вересня 2023, 20:03
в задачке Успішність студента 3 можно же решить все намного проще и легче, благодаря пройденным темам)
for (String names: grades.keySet()
             ) {
            System.out.println(names +" : "+grades.get(names) );

        }
Все выводится как нужно, но валидатор не пустит все равно)))
10 жовтня 2023, 14:16
а можно и так:
for (var entry :
                grades.entrySet()) {
            System.out.println(entry.getKey() + " : " + entry.getValue());
3 строки кода, море удовольствия!
2 липня 2023, 19:13
А як створити об'єкт HashMap і одразу при ініціалізації додати до нього елементи(пари) без метода put?
Jaroslav
Рівень 48
13 грудня 2024, 14:50
Ihor Prokudin
Рівень 51
22 березня 2023, 14:24
Годину сидів і намагався зрозуміти про Set<Entry<>>, сходив по каву і до мене дійшло :/
Roma Chernesh
Рівень 16
8 лютого 2023, 20:17
Ото може в мене одного так, але щось тема із колекціями дуже важкой йде. Знаю, що початківцям зазвичай не вдається зрозуміти роботу подвійних (чи потрійних) масивів. Але якось ту тему вдалося пережувати і втянутися. А тут прям повна каша:(
[V.I.R.U.S.]
Рівень 24
Expert
21 лютого 2023, 17:59
Мужик. ти маєш зрозуміти що все геніальне просте. Не пошкодуй свій час і пройдись назад по темам масивів. Включай в Ютубі різних блогерів+ прочитай 2-3 статті на цю тему від різних авторів. І все стане на свої місця.
Roma Chernesh
Рівень 16
22 лютого 2023, 20:32
Та згоден! Ото який код не побачу по джуві - усюди ці колекції. Тому, каша-не каша, а розуміти треба!
Anonymous #696530
Рівень 19
28 вересня 2022, 17:37
По класу Entry інтуїтивно зрозуміло, що воно все круто і зручно, але самостійно такими речами поки важко оперувати... особливо зі скороченнями.. По Задачі "Успішність студентів-3" скопіював код з лекції і адаптував за 2 хв, таке вже нормально виходить, не знаю добре це чи погано... ))
Andriy
Рівень 20
10 серпня 2022, 09:35
Задачу про перетворення ArrayList в HashMap можна вирішити не замінюючи ArrayList на HashMap, а циклом витягнути з нього індекси і значення, яким потім наповнити HashMap
Pavlo Kezin
Рівень 23
12 вересня 2023, 14:36
теж так робив, але спочатку зробив як у відповіді, але чомусь не пройшло. подумав це було обов"язково.
Lipovskyi Volodymyr
Рівень 36
7 червня 2022, 11:45
Задачка Успішність студентів 2. Не виконано всі вимоги, тому що використовував print замість println))) 25 спроб)))
Andriy
Рівень 16
31 жовтня 2022, 11:56
Не знаю чи поміняли завдяки тобі, але зараз про це вказано: • Метод printStudents має виводити імена та прізвища всіх студентів із колекції grades (кожну пару з нового рядка).