🎯 Kotlin

Wörterbücher und Hashtabellen in Kotlin 1.9: Eine ausführliche Anleitung

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

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

Представь, что у тебя есть волшебная книга. В этой книге на каждой странице написано слово, а рядом — его перевод. Когда ты хочешь узнать перевод, ты просто открываешь книгу на нужном слове. В программировании такая «книга» называется словарём (или хеш-таблицей).

Словарь хранит пары: ключ → значение. Ключ — это то, по чему мы ищем (например, имя друга), а значение — то, что мы хотим получить (например, номер телефона).

В Kotlin для работы со словарями используется тип Map. Он бывает двух видов:

  • mutableMapOf — изменяемый словарь (можно добавлять, удалять, менять)
  • mapOf — неизменяемый словарь (только для чтения)

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

Создадим простой словарь «страна → приветствие»:

fun main() {
    // Создаём изменяемый словарь
    val greetings = mutableMapOf(
        "Россия" to "Привет",
        "Англия" to "Hello",
        "Франция" to "Bonjour"
    )
    
    // Добавляем новую запись
    greetings["Испания"] = "Hola"
    
    // Выводим приветствие для России
    println("В России говорят: ${greetings["Россия"]}")
    
    // Выводим весь словарь
    println("Словарь: $greetings")
}

Вывод программы:

В России говорят: Привет
Словарь: {Россия=Привет, Англия=Hello, Франция=Bonjour, Испания=Hola}

Основные операции со словарями

Давай разберём, что можно делать со словарями в Kotlin:

fun main() {
    // Создаём пустой словарь
    val phoneBook = mutableMapOf<String, String>()
    
    // Добавляем записи
    phoneBook["Маша"] = "+7-999-123-45-67"
    phoneBook["Петя"] = "+7-999-765-43-21"
    
    // Получаем значение по ключу
    val petePhone = phoneBook["Петя"]
    println("Телефон Пети: $petePhone")
    
    // Проверяем, есть ли ключ
    if (phoneBook.containsKey("Маша")) {
        println("Маша есть в справочнике")
    }
    
    // Удаляем запись
    phoneBook.remove("Маша")
    println("После удаления: $phoneBook")
    
    // Количество записей
    println("Всего контактов: ${phoneBook.size}")
}

Вывод:

Телефон Пети: +7-999-765-43-21
Маша есть в справочнике
После удаления: {Петя=+7-999-765-43-21}
Всего контактов: 1

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

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

Нужно создать словарь, где ключ — страна, а значение — приветствие. Пользователь вводит страну, программа выводит приветствие.

fun main() {
    val greetings = mapOf(
        "Россия" to "Привет",
        "Англия" to "Hello",
        "Франция" to "Bonjour",
        "Испания" to "Hola",
        "Германия" to "Hallo"
    )
    
    println("Введите название страны:")
    val country = readLine() ?: ""
    
    if (greetings.containsKey(country)) {
        println("В $country говорят: ${greetings[country]}")
    } else {
        println("Извините, мы не знаем приветствие для $country")
    }
}

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

У нас есть словарь с именами и номерами. Нужно найти номер по имени.

fun main() {
    val phoneBook = mutableMapOf(
        "Анна" to "8-495-111-11-11",
        "Борис" to "8-495-222-22-22",
        "Вика" to "8-495-333-33-33"
    )
    
    println("Введите имя для поиска:")
    val name = readLine() ?: ""
    
    val phone = phoneBook[name]
    if (phone != null) {
        println("Телефон $name: $phone")
    } else {
        println("Контакт не найден")
    }
}

Задача 3: Планировщик дел на неделю

Создаём словарь, где ключ — день недели, а значение — список дел.

fun main() {
    val weekPlan = mutableMapOf<String, MutableList<String>>()
    
    // Добавляем дела на понедельник
    weekPlan["Понедельник"] = mutableListOf("Купить продукты", "Позвонить маме")
    
    // Добавляем дело во вторник
    weekPlan["Вторник"] = mutableListOf("Сходить в спортзал")
    
    // Добавляем ещё одно дело в понедельник
    weekPlan["Понедельник"]?.add("Помыть посуду")
    
    println("План на неделю:")
    for ((day, tasks) in weekPlan) {
        println("$day: ${tasks.joinToString(", ")}")
    }
}

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

  1. Попытка получить значение по несуществующему ключу

    Если ключа нет, map[ключ] вернёт null. Всегда проверяй через containsKey() или используй getOrDefault():

    val value = map.getOrDefault("ключ", "Значение по умолчанию")
  2. Забывают про изменяемость

    Если создаёшь словарь через mapOf, его нельзя изменить. Используй mutableMapOf, если планируешь добавлять или удалять записи.

  3. Путают ключи и значения

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

    val map = mutableMapOf("a" to 1)
    map["a"] = 2  // Теперь map = {"a"=2}
  4. Не используют безопасный вызов для null

    При обращении к словарю всегда используй ?. или проверку на null:

    val value = map["ключ"] ?: "Значение по умолчанию"

Итоговый пример: Цифровой блокнот друзей

Давай напишем программу, которая управляет списком контактов друзей. Можно добавлять, искать и удалять контакты.

fun main() {
    val contacts = mutableMapOf(
        "Иван" to "+7-900-111-22-33",
        "Ольга" to "+7-900-444-55-66",
        "Сергей" to "+7-900-777-88-99"
    )
    
    while (true) {
        println("\n--- Цифровой блокнот ---")
        println("1. Показать все контакты")
        println("2. Найти контакт")
        println("3. Добавить контакт")
        println("4. Удалить контакт")
        println("5. Выйти")
        println("Выберите действие (1-5):")
        
        val choice = readLine() ?: ""
        
        when (choice) {
            "1" -> {
                println("Все контакты:")
                for ((name, phone) in contacts) {
                    println("$name: $phone")
                }
            }
            "2" -> {
                println("Введите имя для поиска:")
                val name = readLine() ?: ""
                val phone = contacts[name]
                if (phone != null) {
                    println("Найден: $name — $phone")
                } else {
                    println("Контакт не найден")
                }
            }
            "3" -> {
                println("Введите имя:")
                val name = readLine() ?: ""
                println("Введите телефон:")
                val phone = readLine() ?: ""
                contacts[name] = phone
                println("Контакт добавлен!")
            }
            "4" -> {
                println("Введите имя для удаления:")
                val name = readLine() ?: ""
                if (contacts.remove(name) != null) {
                    println("Контакт удалён")
                } else {
                    println("Такого контакта нет")
                }
            }
            "5" -> {
                println("До свидания!")
                break
            }
            else -> println("Неверный выбор, попробуйте снова")
        }
    }
}

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

--- Цифровой блокнот ---
1. Показать все контакты
2. Найти контакт
3. Добавить контакт
4. Удалить контакт
5. Выйти
Выберите действие (1-5):
1
Все контакты:
Иван: +7-900-111-22-33
Ольга: +7-900-444-55-66
Сергей: +7-900-777-88-99

Словари — это мощный инструмент, который помогает хранить и быстро находить информацию. В реальных программах они используются повсюду: от хранения настроек до работы с базами данных. Практикуйся, и ты быстро научишься использовать их с лёгкостью!