In Java, a TreeSet is a part of the java.util package and implements the NavigableSet interface, which
extends SortedSet. Internally, it uses a Red-Black Tree (a self-balancing binary search tree), which ensures that
the elements are always stored in sorted order. A TreeSet does not allow duplicate elements and does not permit null
values. It is commonly used when you need to maintain a sorted collection, and it provides log-time complexity for basic
operations like adding, removing, and searching elements.
Advantages #
- Sorted Order: Elements are automatically sorted in natural order (or using a custom comparator), which is useful when maintaining sorted data is required.
- Efficient Range Queries: The TreeSetsupports efficient methods for obtaining subsets, headsets, and tailsets, allowing for quick range-based operations.
- Navigable: Offers convenient methods like first(),last(),lower(), andhigher()for accessing elements based on their values.
- No Duplicates: Ensures that the set contains only unique elements.
- Consistent Performance: Since it is based on a balanced tree, performance remains consistent, even with large data sets.
Disadvantages #
- Slower than HashSet: Operations like add, remove, and search have a time complexity of O(log n), which is slower thanHashSet, which operates inO(1)on average.
- No Null Elements: Does not permit nullvalues, and attempting to add anullelement results in aNullPointerException.
- Higher Memory Overhead: Requires more memory compared to a HashSetdue to the additional structure ( parent/child pointers and color information) of the red-black tree.
- Complexity in Maintaining Order: Maintaining sorted order adds complexity and overhead, making it slower for operations that don’t require ordering.
Time and Space Complexity #
| Operation | Time Complexity | Space Complexity | 
|---|---|---|
| Add (add) | O(log n) | O(n) | 
| Remove (remove) | O(log n) | O(n) | 
| Contains (contains) | O(log n) | O(n) | 
| First (first) | O(log n) | O(n) | 
| Last (last) | O(log n) | O(n) | 
| HeadSet (headSet) | O(log n) | O(n) | 
| TailSet (tailSet) | O(log n) | O(n) | 
| SubSet (subSet) | O(log n) | O(n) | 
Examples #
- Add Operation - Time Complexity: O(log n)
 - TreeSet<Integer> treeSet = new TreeSet<>(); treeSet.add(10); // [10] treeSet.add(5); // [5, 10] treeSet.add(15); // [5, 15, 10] treeSet.add(20); // [5, 15, 10, 20]
- Time Complexity: 
- Remove Operation - Time Complexity: O(log n)
 - treeSet.remove(20); // [5, 15, 10]
- Time Complexity: 
- Contains Operation - Time Complexity: O(log n)
 - treeSet.contains(5); // true
- Time Complexity: 
- First Operation - Time Complexity: O(log n)
 - treeSet.first(); // 5
- Time Complexity: 
- Last Operation - Time Complexity: O(log n)
 - treeSet.last(); // 15
- Time Complexity: 
- HeadSet Operation - Time Complexity: O(log n)
 - treeSet.headSet(10); // [5]
- Time Complexity: 
- TailSet Operation - Time Complexity: O(log n)
 - treeSet.tailSet(10); // [10, 15]
- Time Complexity: 
- SubSet Operation - Time Complexity: O(log n)
 - treeSet.subSet(5, 15); // [5, 10]
- Time Complexity: