JavaRush /Курсы /JAVA 25 SELF /Map: HashMap и TreeMap, ключи и значения

Map: HashMap и TreeMap, ключи и значения

JAVA 25 SELF
26 уровень , 2 лекция
Открыта

1. Введение

В реальной жизни мы часто сталкиваемся с ситуациями, когда каждому уникальному «ключу» нужно сопоставить какое-то «значение». Телефонная книга хранит номер телефона и имя человека, словарь связывает слово с его переводом, а в таблице оценок у каждого студента есть своё имя и соответствующий балл.

В Java для таких задач есть интерфейс Map. Это коллекция, которая хранит пары «ключ — значение» (key-value pair).

Главные свойства Map:

  • Каждый ключ уникален (дубликаты не допускаются).
  • Одному ключу может соответствовать только одно значение.
  • Значения могут повторяться.

Представим аналогию. Если список (List) — это как очередь в столовой (каждый стоит на своей позиции, можно обратиться по номеру), то отображение (Map) — это как шкафчик с ячейками: у каждой ячейки есть номер (ключ), и в ней лежит что-то своё (значение).

Интерфейс Map: базовые операции

Интерфейс Map объявляет основные методы для работы с парами ключ-значение:

Метод Описание
put(K key, V value)
Добавить/заменить значение по ключу
get(K key)
Получить значение по ключу
remove(K key)
Удалить пару по ключу
containsKey(K key)
Проверить, есть ли такой ключ
containsValue(V value)
Проверить, есть ли такое значение
size()
Количество пар в отображении
isEmpty()
Проверить, пустой ли Map
clear()
Удалить все пары

Типы K и V — это generic-параметры: K (Key) — тип ключа, V (Value) — тип значения.

3. Класс HashMap: быстрый доступ по ключу

Что такое HashMap?

HashMap — самая популярная реализация интерфейса Map. Она обеспечивает быстрый доступ к значениям по ключу.

Важно: HashMap не гарантирует порядок хранения элементов! Если вы добавили ключи в определённом порядке, при переборе они могут идти в другом.

Как создать HashMap?

import java.util.HashMap;
import java.util.Map;

public class Example {
    public static void main(String[] args) {
        // Создаём карту: ключ — String, значение — Integer
        Map<String, Integer> ages = new HashMap<>();

        // Добавляем элементы
        ages.put("Вася", 25);
        ages.put("Петя", 30);
        ages.put("Маша", 22);

        // Получаем значение по ключу
        int vasyaAge = ages.get("Вася");
        System.out.println("Возраст Васи: " + vasyaAge); // 25

        // Проверяем наличие ключа
        if (ages.containsKey("Маша")) {
            System.out.println("Маша есть в списке!");
        }

        // Удаляем элемент
        ages.remove("Петя");

        // Перебираем все пары ключ-значение
        for (String name : ages.keySet()) {
            System.out.println(name + ": " + ages.get(name));
        }
    }
}

Вывод:

Возраст Васи: 25
Маша есть в списке!
Вася: 25
Маша: 22

Особенности HashMap

Главное, что стоит помнить: ключи в HashMap всегда уникальны. Если вы положите новый элемент с уже существующим ключом, старое значение будет заменено новым.

Значения могут повторяться: несколько разных ключей могут указывать на одно и то же значение.

И ещё важный момент — порядок элементов. HashMap не заботится о порядке добавления. При выводе записи могут быть перемешаны — это нормальное поведение.

4. Класс TreeMap: сортировка по ключу

В отличие от HashMap, класс TreeMap хранит элементы в отсортированном порядке по ключу.

Когда использовать TreeMap?

Когда важно, чтобы элементы шли по возрастанию (или убыванию) ключей. Например, если вы хотите вывести телефонную книгу по алфавиту.

Пример:

import java.util.Map;
import java.util.TreeMap;

public class TreeMapExample {
    public static void main(String[] args) {
        Map<String, String> phoneBook = new TreeMap<>();

        phoneBook.put("Вася", "+1-900-123-45-67");
        phoneBook.put("Маша", "+1-900-555-55-55");
        phoneBook.put("Петя", "+1-900-222-33-44");

        for (String name : phoneBook.keySet()) {
            System.out.println(name + ": " + phoneBook.get(name));
        }
    }
}

Вывод:

Маша: +1-900-555-55-55
Петя: +1-900-222-33-44
Вася: +1-900-123-45-67

Обратите внимание: ключи отсортированы по алфавиту.

5. Основные операции с Map

Добавление и замена элементов
Map<String, Integer> scores = new HashMap<>();
scores.put("Анна", 90);
scores.put("Иван", 85);
scores.put("Анна", 95); // Перезапишет значение для "Анна"
Получение значения
Integer annaScore = scores.get("Анна"); // 95
Integer unknown = scores.get("Вася");   // null, если такого ключа нет
Проверка наличия ключа или значения
scores.containsKey("Иван");    // true
scores.containsValue(85);      // true
Удаление пары по ключу
scores.remove("Иван");
Размер карты и очистка
int size = scores.size();
scores.clear(); // Удаляет все элементы

5. Перебор элементов Map

Map — это не список, тут нет индексов. Но можно перебирать:

По ключам:

for (String key : scores.keySet()) {
    System.out.println("Ключ: " + key + ", Значение: " + scores.get(key));
}

По значениям:

for (Integer value : scores.values()) {
    System.out.println("Значение: " + value);
}

По парам ключ-значение (лучший способ):

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

Когда использовать HashMap, а когда — TreeMap?

HashMap — универсальный вариант «по умолчанию». Если порядок ключей неважен и главное — скорость операций, почти всегда берут именно его.

TreeMap пригодится, если нужен порядок. Он автоматически хранит ключи отсортированными и позволяет быстро находить минимальный/максимальный ключ или работать с диапазонами.

Итого: в 90% случаев берём HashMap. Когда данные должны быть сразу «в порядке», используем TreeMap.

6. Примеры использования Map

Пример 1: Телефонная книга

Map<String, String> phoneBook = new HashMap<>();
phoneBook.put("Катя", "+1-999-111-22-33");
phoneBook.put("Олег", "+1-999-222-33-44");
phoneBook.put("Катя", "+1-999-555-66-77"); // Старый номер Кати заменится новым

for (Map.Entry<String, String> entry : phoneBook.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

Вывод:

Олег: +1-999-222-33-44
Катя: +1-999-555-66-77

Пример 2: Подсчёт количества слов

Допустим, у нас есть список слов, и мы хотим узнать, сколько раз каждое слово встречается:

import java.util.*;

public class WordCount {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("яблоко", "банан", "яблоко", "груша", "банан", "яблоко");
        Map<String, Integer> counts = new HashMap<>();

        for (String word : words) {
            int oldCount = counts.getOrDefault(word, 0); // если ключа нет — 0
            counts.put(word, oldCount + 1);
        }

        System.out.println(counts); // {груша=1, яблоко=3, банан=2}
    }
}

7. Типичные ошибки при работе с Map

Ошибка №1: Путаница между ключами и значениями. Новички часто пытаются получить значение по индексу, как в списке, или забывают, что ключи должны быть уникальными. В Map нет индексов — только ключи.

Ошибка №2: Использование null-ключей и значений. В HashMap допускается ключ null, но в TreeMap — нет (будет NullPointerException). Значения могут быть null в обеих реализациях, но это редко полезно.

Ошибка №3: Ожидание порядка элементов в HashMap. HashMap не гарантирует никакого порядка. Если нужен порядок — используйте LinkedHashMap (сохраняет порядок добавления) или TreeMap (сортирует по ключу).

Ошибка №4: Модификация Map во время перебора. Если вы в цикле перебираете Map и одновременно добавляете/удаляете элементы — может возникнуть ConcurrentModificationException. Для таких задач используйте итератор с методом remove() или специальные коллекции.

Ошибка №5: Сравнение ключей и значений по == вместо equals. Map использует метод equals для сравнения ключей (и значений). Если вы создаёте свои классы-ключи, обязательно переопределяйте equals и hashCode.

1
Задача
JAVA 25 SELF, 26 уровень, 2 лекция
Недоступна
Умный планировщик задач: дни недели 🗓️
Умный планировщик задач: дни недели 🗓️
1
Задача
JAVA 25 SELF, 26 уровень, 2 лекция
Недоступна
Инвентаризация фруктов на складе по алфавиту 🍏🍌🍐
Инвентаризация фруктов на складе по алфавиту 🍏🍌🍐
Комментарии (4)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Ksanders Уровень 32
11 декабря 2025
А про метод entryset() где-то уже рассказывалось?
Andrey Mityakin Уровень 31
29 января 2026
Да, 12 уровень если не ошибаюсь.
German Malykh Уровень 31
19 октября 2025
В примере вывода для TreeMap есть ошибка

Вывод:
Маша: +7-900-555-55-55
Петя: +7-900-222-33-44
Вася: +7-900-123-45-67
На самом деле вывод будет таким

Вася: +7-900-123-45-67
Маша: +7-900-555-55-55
Петя: +7-900-222-33-44
т. е. имена отсортированы по алфавиту 🙂
Sergey Lunev Уровень 41
9 декабря 2025
они, видимо, были на-английском изначально. Их перевели, а пересортировать забыли