0Pricing
Java Academy · Урок

TreeSet и NavigableSet

Храните уникальные отсортированные элементы и используйте floor, ceiling, higher и lower для поиска ближайших соседей.

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

Что такое TreeSet?

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

import java.util.TreeSet;

TreeSet<String> names = new TreeSet<>();
names.add("Charlie");
names.add("Alice");
names.add("Bob");
names.add("Alice"); // duplicate ignored

for (String s : names) System.out.print(s + " ");
// Alice Bob Charlie

Методы NavigableSet: floor, ceiling, lower, higher

TreeSet реализует NavigableSet, предоставляя методы навигации для поиска ближайших элементов:

TreeSet<Integer> set = new TreeSet<>();
for (int i = 10; i <= 50; i += 10) set.add(i);
// {10, 20, 30, 40, 50}

System.out.println(set.floor(25));   // 20 (greatest ≤ 25)
System.out.println(set.ceiling(25)); // 30 (smallest ≥ 25)
System.out.println(set.lower(30));   // 20 (strictly less)
System.out.println(set.higher(30));  // 40 (strictly greater)

first, last, pollFirst, pollLast

Получайте или удаляйте элементы на границах множества:

TreeSet<String> ts = new TreeSet<>(Set.of("cherry","apple","banana","date"));

System.out.println(ts.first());       // apple
System.out.println(ts.last());        // date
System.out.println(ts.pollFirst());   // apple (removed)
System.out.println(ts.pollLast());    // date (removed)
System.out.println(ts);              // [banana, cherry]

headSet, tailSet, subSet

Извлекайте представления отсортированных подмножеств:

TreeSet<Integer> set = new TreeSet<>(Set.of(1,2,3,4,5,6,7,8,9,10));

System.out.println(set.headSet(5));      // [1, 2, 3, 4]
System.out.println(set.tailSet(7));      // [7, 8, 9, 10]
System.out.println(set.subSet(3, 7));    // [3, 4, 5, 6]

// Inclusive upper bound:
System.out.println(set.subSet(3, true, 7, true)); // [3,4,5,6,7]

Обход в обратном порядке

Используйте descendingIterator() или descendingSet() для обхода в обратном порядке:

TreeSet<Integer> ts = new TreeSet<>(Set.of(1,3,5,7,9));

// Descending iterator
var it = ts.descendingIterator();
while (it.hasNext()) System.out.print(it.next() + " ");
// 9 7 5 3 1

Пользовательский порядок с помощью Comparator

Передайте Comparator, чтобы сортировать элементы не в естественном порядке — например, сначала выводить самые длинные строки:

TreeSet<String> byLength = new TreeSet<>(
    Comparator.comparingInt(String::length)
              .thenComparing(Comparator.naturalOrder())
);
byLength.add("Hi");
byLength.add("Hello");
byLength.add("Hey");
byLength.add("Java");

for (String s : byLength) System.out.print(s + " ");
// Hi Hey Java Hello

Пример применения: отсортированные уникальные имена пользователей

Храните имена пользователей в TreeSet, чтобы автоматически удалять дубликаты и поддерживать алфавитный порядок:

TreeSet<String> users = new TreeSet<>();
users.add("alice");
users.add("bob");
users.add("alice"); // ignored
users.add("carol");

System.out.println(users.first()); // alice
System.out.println(users);         // [alice, bob, carol]

Пример применения: подсчёт в диапазоне

Подсчитывайте элементы в диапазоне с помощью subSet:

TreeSet<Integer> scores = new TreeSet<>();
for (int s : new int[]{45,62,78,55,90,88,34,71}) scores.add(s);

// Scores between 60 and 89 (inclusive)
int count = scores.subSet(60, true, 89, true).size();
System.out.println("Students in B range: " + count); // 3 (62, 78, 88... wait: 62,78,71,88=4)
// Actually: 62,71,78,88 = 4

TreeSet, HashSet и LinkedHashSet

Выбирайте структуру в зависимости от задачи:

  • HashSet: операции O(1), порядок не определён
  • LinkedHashSet: операции O(1), порядок соответствует порядку добавления
  • TreeSet: операции O(log n), отсортированный порядок, методы навигации

Элементы TreeSet должны реализовывать Comparable или использоваться с Comparator.

Элементы null

TreeSet не допускает элементы null при естественном порядке — выбрасывается NullPointerException, поскольку null нельзя сравнить. Будет работать пользовательский компаратор, явно обрабатывающий null.

TreeSet<String> ts = new TreeSet<>();
try {
    ts.add(null); // throws NullPointerException
} catch (NullPointerException e) {
    System.out.println("Cannot add null: " + e);
}

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

TreeSet не поддерживает безопасную работу из нескольких потоков. Синхронизируйте его извне с помощью Collections.synchronizedSortedSet() или используйте ConcurrentSkipListSet, который одновременно поддерживает сортировку и безопасную работу с потоками.

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

В TreeSet<Integer> содержатся элементы {10, 20, 30, 40, 50}. Что возвращает set.ceiling(35)?

Повторение: TreeSet и NavigableSet

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

  • TreeSet хранит уникальные отсортированные элементы (O(log n))
  • Реализует NavigableSet: floor, ceiling, lower, higher, first, last
  • headSet, tailSet и subSet возвращают связанные представления диапазонов
  • Для обратного порядка используйте descendingSet() или descendingIterator()
  • Не поддерживает безопасную работу из нескольких потоков — для параллельной работы используйте ConcurrentSkipListSet

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

Урок «TreeSet и NavigableSet» бесплатный?

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

Чему я научусь в уроке «TreeSet и NavigableSet»?

Храните уникальные отсортированные элементы и используйте floor, ceiling, higher и lower для поиска ближайших соседей. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

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

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

Сколько времени занимает урок «TreeSet и NavigableSet»?

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

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

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

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

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