☕ Java

Словари и хеш-таблицы в Java 17: подробное руководство

Словари и хеш-таблицы в Java

Что такое словарь и зачем он нужен?

Представь, что у тебя есть записная книжка. В ней ты ищешь номер телефона по имени друга. Имя — это ключ, а номер телефона — это значение. В Java для таких пар "ключ-значение" есть специальный инструмент — HashMap (словарь или хеш-таблица).

Словари удобны, когда нужно быстро найти что-то по уникальному имени (ключу). Например:

  • Страна → Приветствие на её языке
  • Имя человека → Номер телефона
  • День недели → Список дел
  • Название товара → Цена

В отличие от списков (ArrayList), где мы ищем по номеру (индексу), в словаре мы ищем по ключу. Это очень быстро!

Основной синтаксис HashMap

Чтобы использовать словарь, нужно подключить библиотеку java.util.HashMap.

import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        // Создаём словарь, где ключ — String, значение — String
        HashMap<String, String> greetings = new HashMap<>();

        // Добавляем пары (ключ, значение)
        greetings.put("Россия", "Здравствуйте");
        greetings.put("Франция", "Bonjour");
        greetings.put("Италия", "Ciao");

        // Получаем значение по ключу
        String russianGreeting = greetings.get("Россия");
        System.out.println("В России говорят: " + russianGreeting);

        // Проверяем, есть ли ключ
        if (greetings.containsKey("Италия")) {
            System.out.println("Италия есть в словаре!");
        }

        // Сколько всего записей
        System.out.println("Всего стран: " + greetings.size());

        // Удаляем запись
        greetings.remove("Франция");
        System.out.println("После удаления: " + greetings.size() + " стран");
    }
}

Результат работы программы:

В России говорят: Здравствуйте
Италия есть в словаре!
Всего стран: 3
После удаления: 2 стран

Типы ключей и значений

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

import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        // Ключ — String (название товара), значение — Double (цена)
        HashMap<String, Double> prices = new HashMap<>();
        prices.put("Яблоки", 89.50);
        prices.put("Молоко", 75.00);
        prices.put("Хлеб", 45.00);

        // Выводим цену яблок
        System.out.println("Цена яблок: " + prices.get("Яблоки") + " руб.");

        // Заменяем цену (ключ уже есть)
        prices.put("Яблоки", 95.00);
        System.out.println("Новая цена яблок: " + prices.get("Яблоки") + " руб.");
    }
}

Результат работы программы:

Цена яблок: 89.5 руб.
Новая цена яблок: 95.0 руб.

Как перебрать все записи в словаре?

Часто нужно пройтись по всем парам "ключ-значение". Для этого используют цикл for-each.

import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        HashMap<String, String> phoneBook = new HashMap<>();
        phoneBook.put("Маша", "8-912-345-67-89");
        phoneBook.put("Петя", "8-923-456-78-90");
        phoneBook.put("Аня", "8-934-567-89-01");

        // Перебираем все записи
        for (String name : phoneBook.keySet()) {
            String phone = phoneBook.get(name);
            System.out.println(name + ": " + phone);
        }
    }
}

Результат работы программы:

Маша: 8-912-345-67-89
Петя: 8-923-456-78-90
Аня: 8-934-567-89-01

Разбор типичных задач

Задача 1: Приветствие для путешественника

У нас есть словарь стран и приветствий. Нужно найти приветствие для заданной страны.

import java.util.HashMap;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        HashMap<String, String> greetings = new HashMap<>();
        greetings.put("Англия", "Hello");
        greetings.put("Испания", "Hola");
        greetings.put("Германия", "Guten Tag");
        greetings.put("Япония", "Konnichiwa");

        Scanner scanner = new Scanner(System.in);
        System.out.print("Введите страну: ");
        String country = scanner.nextLine();

        if (greetings.containsKey(country)) {
            System.out.println("Приветствие: " + greetings.get(country));
        } else {
            System.out.println("Извините, этой страны нет в словаре.");
        }
        scanner.close();
    }
}

Задача 2: Телефонный справочник

Ищем номер телефона по имени. Если имени нет — сообщаем об этом.

import java.util.HashMap;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        HashMap<String, String> contacts = new HashMap<>();
        contacts.put("Иван", "8-111-222-33-44");
        contacts.put("Ольга", "8-555-666-77-88");
        contacts.put("Сергей", "8-999-000-11-22");

        Scanner scanner = new Scanner(System.in);
        System.out.print("Введите имя: ");
        String name = scanner.nextLine();

        String phone = contacts.get(name);
        if (phone != null) {
            System.out.println("Номер телефона: " + phone);
        } else {
            System.out.println("Контакт не найден.");
        }
        scanner.close();
    }
}

Задача 3: Удаление контакта

Удаляем запись из цифрового блокнота по имени.

import java.util.HashMap;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        HashMap<String, String> notebook = new HashMap<>();
        notebook.put("Алексей", "8-123-456-78-90");
        notebook.put("Марина", "8-234-567-89-01");
        notebook.put("Дмитрий", "8-345-678-90-12");

        Scanner scanner = new Scanner(System.in);
        System.out.print("Кого удалить? ");
        String name = scanner.nextLine();

        if (notebook.containsKey(name)) {
            notebook.remove(name);
            System.out.println("Контакт \"" + name + "\" удалён.");
        } else {
            System.out.println("Такого контакта нет.");
        }

        System.out.println("Осталось контактов: " + notebook.size());
        scanner.close();
    }
}

Частые ошибки новичков

  • Забыть импортировать HashMap — без строчки import java.util.HashMap; программа не скомпилируется.
  • Путать ключ и значение — помни: по ключу мы ищем, значение — это то, что хранится.
  • Думать, что ключи могут повторяться — если добавить ключ, который уже есть, он просто заменит старое значение.
  • Использовать get() без проверки — если ключа нет, get() вернёт null. Всегда проверяй через containsKey() или сравнивай с null.
  • Забыть про типы в <> — в угловых скобках нужно указывать, какой тип у ключа и какой у значения: HashMap<String, Integer>.

Итоговый пример: Продуктовый магазин

Создадим программу, которая хранит товары и их цены, позволяет добавлять новые товары, искать цену и выводить весь список.

import java.util.HashMap;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        HashMap<String, Double> shop = new HashMap<>();
        shop.put("Молоко", 75.50);
        shop.put("Хлеб", 42.00);
        shop.put("Сыр", 180.00);
        shop.put("Яблоки", 95.00);

        Scanner scanner = new Scanner(System.in);

        // Добавляем новый товар
        System.out.print("Введите название товара: ");
        String product = scanner.nextLine();
        System.out.print("Введите цену: ");
        double price = scanner.nextDouble();
        scanner.nextLine(); // очищаем буфер

        shop.put(product, price);
        System.out.println("Товар \"" + product + "\" добавлен!");

        // Ищем цену товара
        System.out.print("Введите товар для поиска цены: ");
        String searchProduct = scanner.nextLine();

        if (shop.containsKey(searchProduct)) {
            System.out.println("Цена " + searchProduct + ": " + shop.get(searchProduct) + " руб.");
        } else {
            System.out.println("Товар не найден.");
        }

        // Выводим весь ассортимент
        System.out.println("\nСписок всех товаров:");
        for (String item : shop.keySet()) {
            System.out.println(item + " — " + shop.get(item) + " руб.");
        }

        scanner.close();
    }
}

Пример работы программы:

Введите название товара: Печенье
Введите цену: 55.50
Товар "Печенье" добавлен!
Введите товар для поиска цены: Сыр
Цена Сыр: 180.0 руб.

Список всех товаров:
Молоко — 75.5 руб.
Хлеб — 42.0 руб.
Сыр — 180.0 руб.
Яблоки — 95.0 руб.
Печенье — 55.5 руб.

Вот и всё! Теперь ты знаешь, как работать со словарями в Java. Они помогают хранить данные парами "ключ-значение" и быстро находить нужную информацию. Попробуй решить задачи из раздела — у тебя всё получится!