Java TreeSet class implements the Set interface that uses a tree for storage. It inherits AbstractSet class and implements the NavigableSet interface. The objects of the TreeSet class are stored in ascending order.
The ordering is maintained automatically using a self-balancing tree structure, which makes the TreeSet particularly useful when sorted data is needed. TreeSet does not allow insertion of unordered or duplicate values, and any attempt to do so is simply ignored by the set.

TreeSet is implemented using a self-balancing binary search tree (like a Red-Black Tree). Because of this, operations like search, add, and remove take O(log N) time.
The tree automatically keeps itself balanced, so its height remains small. This makes TreeSet efficient for storing large amounts of sorted data and performing operations quickly.
TreeSet is not synchronized. It means it is not safe to use directly when multiple threads are working on it at the same time.
If one thread is modifying the TreeSet while others are accessing it, then we need to handle synchronization manually.
We can do this by using synchronization techniques or by wrapping the TreeSet using the Collections.synchronizedSet() method. It is better to do this at the time of creation to avoid any issues.
TreeSet treeSet = new TreeSet(); Set syncrSet = Collections.synchronziedSet(treeSet);
As shown in the following diagram, the Java TreeSet class implements the NavigableSet interface.
The NavigableSet interface further extends the SortedSet, Set, Collection, and Iterable interfaces in hierarchical order.
Key Points about TreeSet Hierarchy
Let's see the declaration for java.util.TreeSet class.
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable
Here are the main components of the TreeSet class declaration:
| Constructor | Description |
|---|---|
| TreeSet() | It is used to construct an empty tree set that will be sorted in ascending order according to the natural order of the tree set. Suitable for default sorting needs. |
| TreeSet(Collection<? extends E> c) | It is used to build a new tree set that contains the elements of the collection c. Duplicates are automatically removed. |
| TreeSet(Comparator<? super E> comparator) | It is used to construct an empty tree set that will be sorted according to given comparator. Useful for custom sorting. |
| TreeSet(SortedSet<E> s) | It is used to build a TreeSet that contains the elements of the given SortedSet. Maintains existing sort order. |
| Method | Description |
|---|---|
| boolean add(E e) | It is used to add the specified element to this set if it is not already present. Returns true if the element was added. |
| boolean addAll(Collection<? extends E> c) | It is used to add all of the elements in the specified collection to this set. Ensures all elements are inserted in sorted order. |
| E ceiling(E e) | It returns the equal or closest greatest element of the specified element from the set, or null there is no such element. Useful for range queries. |
| Comparator<? super E> comparator() | It returns a comparator that arranges elements in order. Returns null if natural ordering is used. |
| IteratordescendingIterator() | It is used to iterate the elements in descending order. Provides reverse-order traversal. |
| NavigableSetdescendingSet() | It returns the elements in reverse order. Creates a view of the TreeSet in descending order. |
| E floor(E e) | It returns the equal or closest least element of the specified element from the set, or null there is no such element. Opposite of ceiling(). |
| SortedSetheadSet(E toElement) | It returns the group of elements that are less than the specified element. Excludes the given element. |
| NavigableSetheadSet(E toElement, boolean inclusive) | It returns the group of elements that are less than or equal to (if, inclusive is true) the specified element. Excludes the given element. |
| E higher(E e) | It returns the closest greatest element of the specified element from the set, or null there is no such element. Greater but not equal. |
| Iteratoriterator() | It is used to iterate the elements in ascending order. Default iteration direction. |
| E lower(E e) | It returns the closest least element of the specified element from the set, or null there is no such element. Less but not equal. |
| E pollFirst() | It is used to retrieve and remove the lowest(first) element. Returns null if set is empty. |
| E pollLast() | It is used to retrieve and remove the highest(last) element. Returns null if set is empty. |
| Spliteratorspliterator() | It is used to create a late-binding and fail-fast spliterator over the elements. Useful for parallel iteration. |
| NavigableSetsubSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) | It returns a set of elements that lie between the given range. Inclusion flags allow boundary control. |
| SortedSetsubSet(E fromElement, E toElement)) | It returns a set of elements that lie between the given range which includes fromElement and excludes toElement. Provides partial view. |
| SortedSettailSet(E fromElement) | It returns a set of elements that are greater than or equal to the specified element. Includes fromElement. |
| NavigableSettailSet(E fromElement, boolean inclusive) | It returns a set of elements that are greater than or equal to (if, inclusive is true) the specified element. Supports boundary inclusion logic. |
| boolean contains(Object o) | It returns true if this set contains the specified element. Checks for membership. |
| boolean isEmpty() | It returns true if this set contains no elements. Useful to avoid NullPointerExceptions. |
| boolean remove(Object o) | It is used to remove the specified element from this set if it is present. Returns true if element was found and removed. |
| void clear() | It is used to remove all of the elements from this set. Empties the TreeSet completely. |
| Object clone() | It returns a shallow copy of this TreeSet instance. New copy shares same element references. |
| E first() | It returns the first (lowest) element currently in this sorted set. Useful for boundary access. |
| E last() | It returns the last (highest) element currently in this sorted set. Retrieves the maximum value. |
| int size() | It returns the number of elements in this set. Gives current count of stored elements. |
Java
import java.util.*;
class Main {
public static void main(String args[]){
//Creating and adding elements
TreeSet<String> al=new TreeSet<String>();
al.add("Robert");
al.add("David");
al.add("Maria");
al.add("Mary");
//Traversing elements
Iterator<String> itr=al.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
David Maria Mary Robert
In this example, we are traversing the TreeSet in descending order using descendingIterator().
Java
import java.util.*;
class Main {
public static void main(String args[]){
TreeSet<String> set=new TreeSet<String>();
set.add("John");
set.add("William");
set.add("Michael");
System.out.println("Traversing element through Iterator in descending order");
Iterator i=set.descendingIterator();
while(i.hasNext())
{
System.out.println(i.next());
}
}
}
Output:
Traversing element through Iterator in descending order William Michael John
In this example, we are retrieving and removing the lowest and highest elements.
Java
import java.util.*;
class Main
{
public static void main(String args[]){
TreeSet<Integer> set=new TreeSet<Integer>();
set.add(24);
set.add(66);
set.add(12);
set.add(15);
System.out.println("Lowest Value: "+set.pollFirst());
System.out.println("Highest Value: "+set.pollLast());
}
}
Output:
Lowest Value: 12 Highest Value: 66
In this example, we are performing different NavigableSet operations on TreeSet.
Java
import java.util.*;
class Main {
public static void main(String args[]){
TreeSet<String> set=new TreeSet<String>();
set.add("A");
set.add("B");
set.add("C");
set.add("D");
set.add("E");
System.out.println("Initial Set: "+set);
System.out.println("Reverse Set: "+set.descendingSet());
System.out.println("Head Set: "+set.headSet("C", true));
System.out.println("SubSet: "+set.subSet("A", false, "E", true));
System.out.println("TailSet: "+set.tailSet("C", false));
}
}
Output:
Initial Set: [A, B, C, D, E] Reverse Set: [E, D, C, B, A] Head Set: [A, B, C] SubSet: [B, C, D, E] TailSet: [D, E]
In this example, we are performing SortedSet operations like headSet(), subSet(), and tailSet().
Java
import java.util.*;
class Main
{
public static void main(String args[]){
TreeSet<String> set=new TreeSet<String>();
set.add("A");
set.add("B");
set.add("C");
set.add("D");
set.add("E");
System.out.println("Intial Set: "+set);
System.out.println("Head Set: "+set.headSet("C"));
System.out.println("SubSet: "+set.subSet("A", "E"));
System.out.println("TailSet: "+set.tailSet("C"));
}
}
Output:
Intial Set: [A, B, C, D, E] Head Set: [A, B] SubSet: [A, B, C, D] TailSet: [C, D, E]
In this example, we are storing user-defined objects in TreeSet using the Comparable interface.
Java
import java.util.*;
// Defining the Book class that implements Comparable interface to allow sorting by id
class Book implements Comparable<Book> {
int id; // Book ID
String name; // Book Name
String author; // Author Name
String publisher; // Publisher Name
int quantity; // Quantity of books
// Constructor to initialize Book object
public Book(int id, String name, String author, String publisher, int quantity) {
this.id = id;
this.name = name;
this.author = author;
this.publisher = publisher;
this.quantity = quantity;
}
// compareTo method overridden to sort books by id in ascending order
public int compareTo(Book b) {
return Integer.compare(this.id, b.id); // more concise and safe comparison
}
}
public class Main {
// main method to execute the program
public static void main(String[] args) {
// Creating a TreeSet of Book. TreeSet will maintain elements in sorted order based on Book ID.
Set<Book> set = new TreeSet<Book>();
// Creating Book objects
Book b1 = new Book(121, "Let us C", "Yashwant Kanetkar", "BPB", 8);
Book b2 = new Book(233, "Operating System", "Galvin", "Wiley", 6);
Book b3 = new Book(101, "Data Comm", "Forouzan", "Mc Graw Hill", 4);
// Adding Book objects to TreeSet
set.add(b1);
set.add(b2);
set.add(b3);
// Iterating over the TreeSet
// The books will be printed in order based on their IDs (101, 121, 233)
for (Book b : set) {
System.out.println(b.id + " " + b.name + " " + b.author + " " + b.publisher + " " + b.quantity);
}
}
}
Output:
101 Data Comm Forouzan Mc Graw Hill 4 121 Let us C Yashwant Kanetkar BPB 8 233 Operating System Galvin Wiley 6
In this example, we are adding objects that do not implement Comparable, which causes an exception.
Java
import java.util.*;
class Employee {
int empId;
String name;
}
class Main {
public static void main(String[] args){
TreeSet<Employee> set = new TreeSet<Employee>();
set.add(new Employee());
set.add(new Employee());
}
}
Output:
ClassCastException
The following table shows the difference between TreeSet and HashSet:
| Feature | TreeSet | HashSet |
|---|---|---|
| Underlying Data Structure | Red-Black Tree | Hash Table |
| Ordering of Elements | Keeps elements sorted, which facilitates ordered traversal and quick-range searches. | Does not maintain any order; element arrangement is determined by the hash function. |
| Performance for Basic Operations | Somewhat increased temporal complexity; operations like add, delete, and contain are ?(log?)O(logN). | Constant-time complexity ?(1)O(1) for basic operations like add, delete, and contain, making it highly efficient. |
| Best Use Case | Better suited for applications requiring ordered data management, such as range queries or sequential access. | Ideal for scenarios where quick retrieval and manipulation are more important than element order. |
| Sorting | Automatically sorts elements according to their natural ordering or a specified comparator. | No sorting of elements; storage is hash-based. |
| Application Suitability | Preferred for applications where elements need to be maintained in a sorted manner. | More suitable for applications requiring fast access and where element order is not a concern. |
We request you to subscribe our newsletter for upcoming updates.