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 = 4TreeSet, 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 — локальная установка не требуется.
Все уроки этого курса
- TreeMap: отсортированные пары ключ–значение
- Подкарты и представления диапазонов
- TreeSet и NavigableSet
- Пользовательский порядок в древовидных коллекциях