← Back to Home

TreeSet

TreeSet is an implementation of the Set interface that stores unique elements in sorted order. It is backed by a self-balancing Red-Black Tree, providing ordered iteration and logarithmic-time operations. This is a high-frequency interview topic, commonly compared with HashSet and LinkedHashSet.

What Is TreeSet?

  • Sorted set implementation
  • Stores unique elements only
  • Maintains ascending (natural) order by default
  • Does not allow null
  • Part of java.util package
Set<Integer> set = new TreeSet<>();
          

Position in Collection Hierarchy

Iterable
   └── Collection
        └── Set
             └── SortedSet
                   └── NavigableSet
                         └── TreeSet
          

How TreeSet Works Internally (Interview Favorite)

  • Backed by a Red-Black Tree
  • Elements compared using:
  • Natural ordering (Comparable)
  • Custom ordering (Comparator)
  • Guarantees sorted traversal at all times

Key Characteristics of TreeSet

  • Sorted order maintained automatically
  • No duplicates
  • No null elements
  • Slower than HashSet / LinkedHashSet
  • Not synchronized (not thread-safe)

Creating a TreeSet

1️⃣ Natural Ordering

TreeSet<Integer> set = new TreeSet<>();
set.add(30);
set.add(10);
set.add(20);

System.out.println(set); // [10, 20, 30]
          

2️⃣ Custom Ordering (Comparator)

TreeSet<Integer> set = new TreeSet<>((a, b) -> b - a);
set.add(10);
set.add(30);
set.add(20);

System.out.println(set); // [30, 20, 10]
          

✔ Descending order

Important Methods (Sorted & Navigable Operations)

set.first();        // smallest element
set.last();         // largest element
set.lower(20);      // < 20
set.higher(20);     // > 20
set.floor(20);      // <= 20
set.ceiling(20);    // >= 20
          

Duplicate Handling Example

TreeSet<String> set = new TreeSet<>();
set.add("Java");
set.add("Java");

System.out.println(set); // [Java]
          
  • ✔ Duplicate ignored
  • ✔ No exception thrown

Null Handling (Very Important)

TreeSet<String> set = new TreeSet<>();
set.add(null); // ❌ NullPointerException
          

❌ null not allowed because comparison is required

Performance Complexity

Operation Time Complexity
add O(log n)
remove O(log n)
contains O(log n)
iteration O(n)

TreeSet vs HashSet vs LinkedHashSet (Interview Table)

Feature HashSet LinkedHashSet TreeSet
Order ❌ None ✔ Insertion ✔ Sorted
Performance Fastest Fast Slowest
Null allowed ✔ One ✔ One ❌ No
Internal DS HashMap LinkedHashMap Red-Black Tree

When to Use TreeSet

  • Sorted data required
  • Range queries needed (headSet, tailSet)
  • Ordered traversal is mandatory
  • Duplicate elimination + sorting

When NOT to Use TreeSet

  • Maximum performance is required
  • null values must be stored
  • Order does not matter
  • Large datasets with frequent inserts (prefer HashSet)

Common Beginner Mistakes

  • Adding null values
  • Forgetting to implement Comparable for custom objects
  • Assuming faster than HashSet
  • Using TreeSet when sorting is unnecessary

TreeSet Examples

1. Creating a TreeSet (Natural Sorting)

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<>();
        set.add(30);
        set.add(10);
        set.add(20);
        System.out.println(set);
    }
}
          

Output

[10, 20, 30]

2. TreeSet Does Not Allow Duplicates

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<>();
        set.add("Java");
        set.add("Java");
        System.out.println(set.size());
    }
}
          

Output

1

3. TreeSet Does NOT Allow null

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<>();
        // set.add(null); // ❌ NullPointerException
        System.out.println("Null not allowed");
    }
}
          

4. Sorting Strings Alphabetically

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<>();
        set.add("Banana");
        set.add("Apple");
        set.add("Orange");
        System.out.println(set);
    }
}
          

Output

[Apple, Banana, Orange]

5. Sorting in Reverse Order (Comparator)

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<>(Comparator.reverseOrder());
        set.add(10);
        set.add(30);
        set.add(20);
        System.out.println(set);
    }
}
          

Output

[30, 20, 10]

6. Custom Sorting Using Comparator

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<String> set =
            new TreeSet<>((a, b) -> a.length() - b.length());
        set.add("Java");
        set.add("API");
        set.add("Automation");
        System.out.println(set);
    }
}
          

Output

[API, Java, Automation]

7. Iterating Using for-each

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set =
            new TreeSet<>(Arrays.asList(1, 2, 3));
        for (int x : set) {
            System.out.println(x);
        }
    }
}
          

8. Iterating Using Iterator

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<String> set =
            new TreeSet<>(Arrays.asList("A", "B", "C"));
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}
          

9. Removing Elements

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set =
            new TreeSet<>(Arrays.asList(10, 20, 30));
        set.remove(20);
        System.out.println(set);
    }
}
          

Output

[10, 30]

10. first() and last()

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set =
            new TreeSet<>(Arrays.asList(10, 20, 30));
        System.out.println(set.first());
        System.out.println(set.last());
    }
}
          

Output

10
30
          

11. headSet() – Elements Less Than Given Value

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set =
            new TreeSet<>(Arrays.asList(10, 20, 30, 40));
        System.out.println(set.headSet(30));
    }
}
          

Output

[10, 20]

12. tailSet() – Elements Greater Than or Equal

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set =
            new TreeSet<>(Arrays.asList(10, 20, 30, 40));
        System.out.println(set.tailSet(30));
    }
}
          

Output

[30, 40]

13. subSet() – Range View

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set =
            new TreeSet<>(Arrays.asList(10, 20, 30, 40));
        System.out.println(set.subSet(20, 40));
    }
}
          

Output

[20, 30]

14. Navigational Methods (lower, higher, floor, ceiling)

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set =
            new TreeSet<>(Arrays.asList(10, 20, 30));
        System.out.println(set.lower(20));
        System.out.println(set.higher(20));
        System.out.println(set.floor(25));
        System.out.println(set.ceiling(25));
    }
}
          

Output

10
30
20
30
          

15. Polling Elements (pollFirst, pollLast)

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> set =
            new TreeSet<>(Arrays.asList(10, 20, 30));
        System.out.println(set.pollFirst());
        System.out.println(set.pollLast());
        System.out.println(set);
    }
}
          

Output

10
30
[20]
          

16. Converting List to TreeSet (Sort + Remove Duplicates)

import java.util.*;

class Demo {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(3, 1, 2, 2);
        TreeSet<Integer> set = new TreeSet<>(list);
        System.out.println(set);
    }
}
          

Output

[1, 2, 3]

17. Custom Objects with Comparable

class User implements Comparable<User> {
    int id;
    User(int id) { this.id = id; }

    public int compareTo(User u) {
        return this.id - u.id;
    }
}

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<User> set = new TreeSet<>();
        set.add(new User(2));
        set.add(new User(1));
        System.out.println(set.size());
    }
}
          

Output

2

18. Custom Objects with Comparator

import java.util.*;

class User {
    int id;
    User(int id) { this.id = id; }
}

class Demo {
    public static void main(String[] args) {
        TreeSet<User> set =
            new TreeSet<>((a, b) -> a.id - b.id);
        set.add(new User(2));
        set.add(new User(1));
        System.out.println(set.size());
    }
}
          

19. Performance Note (Concept)

TreeSet<Integer> set = new TreeSet<>();

Explanation

  • Backed by Red-Black Tree
  • Operations are O(log n)
  • Slower than HashSet, faster ordered access

20. Interview Summary – TreeSet

import java.util.*;

class Demo {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<>();
        set.add("Sorted");
        set.add("Unique");
        System.out.println(set);
    }
}
          

Key Points

  • Sorted set
  • No duplicates
  • No null allowed
  • Uses Red-Black Tree
  • Supports navigational methods

Interview-Ready Answers

Short Answer

TreeSet is a Set implementation that stores elements in sorted order.

Detailed Answer

In Java, TreeSet implements the NavigableSet interface and stores unique elements in sorted order using a Red-Black Tree. It does not allow null elements and provides logarithmic-time performance for basic operations.

Key Takeaway

Use TreeSet when you need sorted, unique elements. Accept the performance trade-off in exchange for automatic ordering and rich navigation APIs.