0Pricing
Java Academy · Урок

TreeMap: отсортированные пары ключ–значение

Используйте TreeMap для поддержания сортированного порядка и навигации с помощью firstKey, lastKey, floorKey и ceilingKey.

«TreeMap: отсортированные пары ключ–значение» — бесплатный урок Java Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.

Что такое TreeMap?

TreeMap — реализация отсортированной карты на основе красно-чёрного дерева. Ключи поддерживаются в порядке возрастания согласно естественному порядку или пользовательскому компаратору. Все основные операции имеют сложность O(log n).

import java.util.TreeMap;

TreeMap<String, Integer> scores = new TreeMap<>();
scores.put("Charlie", 85);
scores.put("Alice", 92);
scores.put("Bob", 78);

// Iteration is in key order: Alice, Bob, Charlie
for (var entry : scores.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

firstKey, lastKey, floorKey, ceilingKey

Интерфейс NavigableMap TreeMap предоставляет методы навигации для поиска ключей относительно заданного значения:

TreeMap<Integer, String> map = new TreeMap<>();
map.put(10, "ten"); map.put(20, "twenty"); map.put(30, "thirty"); map.put(40, "forty");

System.out.println(map.firstKey());       // 10
System.out.println(map.lastKey());        // 40
System.out.println(map.floorKey(25));     // 20 (largest key ≤ 25)
System.out.println(map.ceilingKey(25));   // 30 (smallest key ≥ 25)
System.out.println(map.lowerKey(20));     // 10 (strictly less)
System.out.println(map.higherKey(20));    // 30 (strictly greater)

Навигация по записям

floorEntry, ceilingEntry, firstEntry и lastEntry возвращают полный объект Map.Entry, а не только ключ:

TreeMap<Integer, String> prices = new TreeMap<>();
prices.put(100, "Budget"); prices.put(300, "Standard"); prices.put(700, "Premium");

var entry = prices.floorEntry(350);
System.out.println(entry.getKey() + ": " + entry.getValue()); // 300: Standard

var top = prices.lastEntry();
System.out.println(top.getValue()); // Premium

subMap, headMap, tailMap

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

TreeMap<Integer, String> map = new TreeMap<>();
for (int i = 1; i <= 10; i++) map.put(i, "v"+i);

// Keys from 3 (inclusive) to 7 (exclusive)
System.out.println(map.subMap(3, 7));   // {3=v3, 4=v4, 5=v5, 6=v6}

// Keys strictly less than 5
System.out.println(map.headMap(5));     // {1=v1, 2=v2, 3=v3, 4=v4}

// Keys >= 7
System.out.println(map.tailMap(7));     // {7=v7, 8=v8, 9=v9, 10=v10}

Включаемые и исключаемые границы

Используйте перегруженные варианты методов для точного управления границами:

TreeMap<Integer, String> map = new TreeMap<>();
for (int i = 1; i <= 10; i++) map.put(i*10, "v"+i);

// From 30 (inclusive) to 60 (inclusive)
System.out.println(map.subMap(30, true, 60, true));
// {30=v3, 40=v4, 50=v5, 60=v6}

Порядок descending

Используйте descendingMap() или descendingKeySet(), чтобы обходить ключи в обратном порядке:

TreeMap<String, Integer> tm = new TreeMap<>();
tm.put("A", 1); tm.put("C", 3); tm.put("B", 2);

for (String key : tm.descendingKeySet()) {
    System.out.print(key + " "); // C B A
}

pollFirstEntry и pollLastEntry

Атомарно удаляйте и возвращайте первую или последнюю запись — это удобно для построения карт приоритетов:

TreeMap<Integer, String> events = new TreeMap<>();
events.put(8, "Breakfast");
events.put(12, "Lunch");
events.put(18, "Dinner");

var first = events.pollFirstEntry(); // removes 8=Breakfast
System.out.println(first.getValue() + " removed");
System.out.println(events.firstKey()); // 12

Пример применения: таблица лидеров

В таблице лидеров игроки должны быть отсортированы по результату. TreeMap автоматически сортирует записи по ключу:

TreeMap<Integer, String> leaderboard = new TreeMap<>(Comparator.reverseOrder());
leaderboard.put(1200, "Alice");
leaderboard.put(1500, "Bob");
leaderboard.put(900, "Carol");

int rank = 1;
for (var e : leaderboard.entrySet()) {
    System.out.println(rank++ + ". " + e.getValue() + " (" + e.getKey() + ")");
}
// 1. Bob (1500)
// 2. Alice (1200)
// 3. Carol (900)

Пример применения: планировщик событий

Связывайте временные метки с событиями и используйте ceilingEntry, чтобы найти следующее запланированное событие после заданного времени:

import java.time.LocalTime;
TreeMap<LocalTime, String> schedule = new TreeMap<>();
schedule.put(LocalTime.of(9,0), "Standup");
schedule.put(LocalTime.of(14,0), "Review");
schedule.put(LocalTime.of(17,0), "Retro");

LocalTime now = LocalTime.of(11, 30);
var next = schedule.ceilingEntry(now);
System.out.println("Next: " + next.getValue()); // Review

Производительность TreeMap и HashMap

Основное сравнение:

  • HashMap: get/put в среднем имеют сложность O(1); порядок не определён
  • TreeMap: get/put имеют сложность O(log n); сортировка выполняется по ключу
  • LinkedHashMap: в среднем O(1); порядок соответствует порядку добавления

Используйте TreeMap, когда нужны отсортированные ключи или запросы по диапазону. Для простого поиска по ключу HashMap работает быстрее.

Безопасность при работе с потоками

TreeMap не поддерживает безопасную работу из нескольких потоков. Для параллельного доступа используйте ConcurrentSkipListMap, который также сохраняет отсортированный порядок, обеспечивает операции сложности O(log n) и поддерживает одновременное чтение и запись.

Быстрая проверка

У Вас есть TreeMap<Integer, String> с ключами {10, 20, 30, 40}. Что возвращает map.floorKey(25)?

Повторение: TreeMap

Основные выводы:

  • TreeMap поддерживает ключи в отсортированном порядке возрастания с помощью красно-чёрного дерева
  • Все операции имеют сложность O(log n)
  • Навигация: firstKey, lastKey, floorKey, ceilingKey, lowerKey, higherKey
  • Представления диапазонов: subMap, headMap, tailMap, связанные с исходной картой
  • Для безопасных при параллельной работе отсортированных карт используйте ConcurrentSkipListMap

Часто задаваемые вопросы

Урок «TreeMap: отсортированные пары ключ–значение» бесплатный?

Да — полный текст урока «TreeMap: отсортированные пары ключ–значение» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.

Чему я научусь в уроке «TreeMap: отсортированные пары ключ–значение»?

Используйте TreeMap для поддержания сортированного порядка и навигации с помощью firstKey, lastKey, floorKey и ceilingKey. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «TreeMap: отсортированные пары ключ–значение»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. TreeMap: отсортированные пары ключ–значение
  2. Подкарты и представления диапазонов
  3. TreeSet и NavigableSet
  4. Пользовательский порядок в древовидных коллекциях
← Назад к Java Academy