Класс Java TreeSet расширяет AbstractSet и реализует интерфейс NavigableSet. Он очень похож на класс HashSet, за исключением того, что он хранит элемент в отсортированном порядке.
Порядок сортировки может быть естественным или с использованием компаратора, предоставленного во время создания набора деревьев, в зависимости от того, какой конструктор используется.
1. Иерархия TreeSet
Класс TreeSet расширяет класс AbstractSet и реализует интерфейс NavigableSet. Интерфейс NavigableSet расширяет SortedSet в иерархическом порядке.
class TreeSet<E> extends AbstractSet<E>implements NavigableSet<E>, Cloneable, Serializable{//implementation}

2. Возможности TreeSet
- Он расширяет класс AbstractSet, который расширяет класс AbstractCollection.
- Он реализует интерфейс NavigableSet, который расширяет интерфейс SortedSet.
- В TreeSet не допускаются повторяющиеся значения.
- Значение NULL не допускается в TreeSet.
- Это упорядоченная коллекция, в которой элементы хранятся в отсортированном порядке.
- Как и HashSet, этот класс обеспечивает постоянную производительность по времени для основных операций(добавление, удаление, содержание и размер).
- TreeSet не позволяет вставлять разнородные объекты, поскольку для определения порядка сортировки необходимо сравнивать объекты.
- TreeSet не синхронизирован. Если несколько потоков одновременно обращаются к набору хэшей и хотя бы один из потоков изменяет набор, он должен быть синхронизирован извне.
- Используйте метод Collections.synchronizedSortedSet(new TreeSet()) для получения синхронизированного TreeSet.
- Итераторы, возвращаемые методом итератора этого класса, являются отказоустойчивыми и могут выдать исключение ConcurrentModificationException, если набор будет изменен в любое время после создания итератора любым способом, кроме как с помощью собственного метода итератора remove().
- TreeSet также реализует интерфейсы Searlizable и Cloneable.
3. Конструкторы TreeSet
TreeSet имеет четыре возможных конструктора:
- TreeSet(): создает новый пустой набор деревьев, отсортированный в соответствии с естественным порядком его элементов.
- TreeSet(Comparator c): создает новый пустой набор деревьев, отсортированный в соответствии с указанным компаратором.
- TreeSet(SortedSet s): создает новый набор деревьев, содержащий те же элементы и использующий тот же порядок, что и указанный отсортированный набор.
- TreeSet(Collection c): создает новый набор деревьев, содержащий элементы указанной коллекции, отсортированные в соответствии с естественным порядком ее элементов.
4. Методы TreeSet
- boolean add(E e) : добавляет указанный элемент в набор, если он еще не присутствует.
- Компаратор comparator() : возвращает компаратор, используемый для упорядочивания элементов в этом наборе, или null, если этот набор использует естественный порядок своих элементов.
- Object first() : возвращает первый(самый низкий) элемент в текущем наборе.
- Object last() : возвращает последний(наибольший) элемент в этом наборе.
- void clear() : удаляет все элементы из TreeSet.
- boolean contains(Object o) : возвращает true, если TreeSet содержит указанный элемент, в противном случае возвращает false.
- boolean isEmpty() : возвращает true, если TreeSet не содержит ни одного элемента, в противном случае false.
- int size() : возвращает количество элементов в TreeSet.
- Iterator<E> iterator() : возвращает итератор по элементам в этом наборе в порядке возрастания.
- Iterator<E> descendingIterator() : возвращает итератор по элементам в этом наборе в порядке убывания.
- NavigableSet<E> descendingSet() : возвращает обратный порядок элементов, содержащихся в этом наборе.
- boolean remove(Object o) : удаляет указанный элемент из TreeSet, если он присутствует, и возвращает true, в противном случае возвращает false.
- Object clone() : возвращает поверхностную копию TreeSet.
- Spliterator<E> spliterator() : создает Spliterator с поздним связыванием и быстрым отказом для элементов в этом TreeSet. Он имеет тот же порядок, что и treeset.
5. Пример набора деревьев
5.1. Пример добавления, удаления итератора TreeSet
//1. Create TreeSetTreeSet<String> TreeSet = new TreeSet<>();//2. Add elements to TreeSetTreeSet.add("A");TreeSet.add("B");TreeSet.add("C");TreeSet.add("D");TreeSet.add("E");System.out.println(TreeSet);//3. Check if element existsboolean found = TreeSet.contains("A"); //trueSystem.out.println(found);//4. Remove an elementTreeSet.remove("D");//5. Iterate over valuesIterator<String> itr = TreeSet.iterator();while(itr.hasNext()){String value = itr.next();System.out.println("Value: " + value);}
Вывод программы.
[A, B, C, D, E]trueValue: AValue: BValue: CValue: E
5.2 Пример преобразования TreeSet в массив
Пример Java для преобразования TreeSet в массив с помощью метода toArrray().
TreeSet<String> TreeSet = new TreeSet<>();TreeSet.add("A");TreeSet.add("B");TreeSet.add("C");TreeSet.add("D");TreeSet.add("E");String[] values = new String[TreeSet.size()];TreeSet.toArray(values);System.out.println(Arrays.toString(values));
Вывод программы.
[A, B, C, D, E]
5.3 Пример преобразования TreeSet в ArrayList
Пример Java для преобразования TreeSet в arraylist с использованием потокового API Java 8.
TreeSet<String> TreeSet = new TreeSet<>();TreeSet.add("A");TreeSet.add("B");TreeSet.add("C");TreeSet.add("D");TreeSet.add("E");List<String> valuesList = TreeSet.stream().collect(Collectors.toList());System.out.println(valuesList);
Вывод программы.
[A, B, C, D, E]
6. Варианты использования TreeSet
TreeSet очень похож на HashSet(уникальные элементы) и обеспечивает предсказуемый порядок итерации(сортировка). Сортировка может быть переопределена с помощью пользовательского компаратора.
TreeSet использует красно-черное дерево под капотом. Таким образом, набор можно рассматривать как динамическое дерево поиска. Когда вам нужна структура, которая часто используется для чтения/записи и также должна поддерживать порядок, TreeSet — хороший выбор.
Если вы хотите сохранить коллекцию отсортированной и в основном добавляете элементы, лучшим выбором будет TreeSet с компаратором.
7. Производительность TreeSet
- TreeSet обеспечивает гарантированные затраты времени log(n) на основные операции(добавление, удаление и содержание).
- Такие операции, как перебор элементов в отсортированном порядке, занимают O(n) времени.
8. Заключение
Из вышеизложенного обсуждения очевидно, что TreeSet — очень полезный класс коллекции в случаях, когда мы хотим обрабатывать дубликаты записей в отсортированном виде. Он также обеспечивает предсказуемую производительность для основных операций.
Если сортировка элементов не требуется, то рекомендуется использовать более легкие HashSet и HashMap.
Пишите мне в комментариях свои вопросы, связанные с TreeSet в Java.
Ссылка: