TreeSet in Java: Complete Enterprise Guide with Internal Working, Spring Boot Microservice, and Real-World Examples

A complete enterprise-level guide to Java TreeSet covering internal Red-Black Tree working, sorting, duplicate handling, Comparator design, Spring Boot microservice examples, real-world usage, future scope, and interview preparation.

TreeSet in Java: Complete Enterprise Guide with Internal Working and Real-World Microservice Examples

TreeSet is one of the most important sorted collection implementations in Java. It is used when an application needs unique elements while maintaining automatic sorting. Internally, TreeSet uses a Red-Black Tree data structure to provide efficient insertion, deletion, and searching operations.

In enterprise applications, TreeSet is commonly used for scenarios such as product catalogs, ranking systems, scheduling systems, reports, and any business logic where data needs to remain sorted without manually sorting after every update.

What is TreeSet in Java?

TreeSet is a class from java.util package that implements the SortedSet and NavigableSet interfaces. It stores unique elements in sorted order according to their natural ordering or a custom Comparator.

import java.util.TreeSet;

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

numbers.add(30);
numbers.add(10);
numbers.add(20);

System.out.println(numbers);

Output: [10, 20, 30]. TreeSet automatically sorted the values without any explicit sorting operation.

Why Was TreeSet Introduced?

Before TreeSet, developers often used ArrayList and manually sorted data using Collections.sort(). This approach becomes inefficient when data changes frequently because every update may require another sorting operation.

  • Automatically keeps elements sorted
  • Does not allow duplicate elements
  • Provides searching operations like higher(), lower(), ceiling(), and floor()
  • Provides efficient O(log n) insertion and searching

TreeSet Internal Working

TreeSet internally uses TreeMap. The actual data structure is a Red-Black Tree. When you add an element, TreeSet stores it as a key inside TreeMap.

TreeSet
   |
   | internally uses
   v
TreeMap
   |
   v
Red-Black Tree
   |
   v
Sorted Nodes

A Red-Black Tree is a self-balancing binary search tree. It automatically adjusts its structure after insertions and deletions so that the height remains balanced.

How TreeSet Adds an Element Internally

treeSet.add(50)

Step 1:
Check existing tree

Step 2:
Compare new value using compareTo() or Comparator

Step 3:
Find correct position

Step 4:
Insert node

Step 5:
Balance Red-Black Tree if required

TreeSet Duplicate Handling

TreeSet does not use equals() directly to identify duplicates. It uses compareTo() or Comparator. If comparison returns zero, TreeSet considers both objects equal and rejects the duplicate.

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

set.add(100);
set.add(100);

System.out.println(set);

Output: [100]. The second value is ignored because compareTo() returns zero.

Comparable vs Comparator in TreeSet

TreeSet needs a way to understand how objects should be sorted. Java provides two approaches: Comparable and Comparator. Comparable defines the natural ordering inside the class itself, while Comparator provides external sorting logic.

Using Comparable

class Product implements Comparable<Product> {

    private int id;
    private double price;

    @Override
    public int compareTo(Product other) {
        return Double.compare(this.price, other.price);
    }
}

Here the Product class itself decides that products should be sorted by price.

Using Comparator

TreeSet<Product> products = new TreeSet<>(
    Comparator.comparing(Product::getPrice)
);

Comparator is preferred in enterprise applications because the same object may require multiple sorting strategies. For example, products may be sorted by price, rating, popularity, or discount.

Real World Example: Product Catalog Microservice

Consider an e-commerce company like Amazon or Flipkart. The Product Catalog service receives products from the database and needs to return them sorted by price.

Customer Request
       |
       v
Product Controller
       |
       v
Product Service
       |
       v
Database
       |
       v
TreeSet Sorting
       |
       v
JSON Response

Product Entity

public class Product {

    private Long id;
    private String name;
    private double price;

    public Product(Long id, String name, double price){
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public Long getId(){
        return id;
    }

    public double getPrice(){
        return price;
    }

    public String getName(){
        return name;
    }
}

Product Service Using TreeSet

@Service
public class ProductService {

    private final ProductRepository repository;

    public ProductService(ProductRepository repository){
        this.repository = repository;
    }

    public Set<Product> getProducts(){

        TreeSet<Product> products =
            new TreeSet<>(
                Comparator.comparing(Product::getPrice)
                          .thenComparing(Product::getId)
            );

        products.addAll(repository.findAll());

        return products;
    }
}

The thenComparing(Product::getId) is important. If two products have the same price, the ID is used to differentiate them. Without this, one product could disappear because TreeSet would consider both products duplicates.

Duplicate Price Problem in Product Systems

Real businesses have many products with the same price. For example, multiple mobile phones may cost ₹30,000. Therefore, comparing only price is incorrect.

Comparator<Product> comparator =
    Comparator.comparing(Product::getPrice);

Problem: Two products with price 30000 return comparison result 0. TreeSet treats them as duplicates.

iPhone   30000
Samsung  30000

Comparator result:
30000 == 30000

Result:
Only one product stored

Correct Enterprise Comparator

Comparator<Product> comparator =
    Comparator.comparing(Product::getPrice)
              .thenComparing(Product::getId);

Now products are sorted by price first and product ID second. Multiple products with the same price can safely exist.

TreeSet Navigation Methods

TreeSet implements NavigableSet, which provides powerful searching operations used in enterprise applications.

  • first() returns the smallest element
  • last() returns the largest element
  • higher() returns element greater than given value
  • lower() returns element smaller than given value
  • ceiling() returns element greater than or equal to value
  • floor() returns element smaller than or equal to value
TreeSet<Integer> prices = new TreeSet<>();

prices.add(100);
prices.add(200);
prices.add(300);

System.out.println(prices.higher(200));
System.out.println(prices.lower(200));

Output: higher(200) returns 300 and lower(200) returns 100.

Spring Boot REST API Using TreeSet

In a real Spring Boot application, the controller receives a request from the customer. The service layer fetches data from the database and uses TreeSet to maintain sorted unique products before returning the response.

Product Controller

@RestController
@RequestMapping("/products")
public class ProductController {

    private final ProductService service;

    public ProductController(ProductService service){
        this.service = service;
    }

    @GetMapping
    public Set<Product> getProducts(){
        return service.getProducts();
    }
}

When a customer calls GET /products, Spring creates a request thread. The service executes the business logic and returns sorted products.

Complete Request Flow

Browser / Mobile App
          |
          v
GET /products
          |
          v
ProductController
          |
          v
ProductService
          |
          v
ProductRepository
          |
          v
Database
          |
          v
TreeSet Sorting
          |
          v
JSON Response

Filtering Products Using TreeSet Range Operations

One advantage of TreeSet is that data is already sorted. Applications can quickly retrieve ranges without sorting again.

TreeSet<Product> products = new TreeSet<>(comparator);

NavigableSet<Product> result =
    products.subSet(
        new Product(0,"",20000),
        true,
        new Product(Long.MAX_VALUE,"",50000),
        true
    );

This can be used for features like: show products between ₹20,000 and ₹50,000, show vehicles between price ranges, or show employees within salary ranges.

Finding Cheapest and Most Expensive Products

Product cheapest = products.first();

Product expensive = products.last();

E-commerce applications frequently need these operations for recommendations, discounts, and analytics.

TreeSet and Pagination

TreeSet itself does not provide database-style pagination, but its sorted nature helps implement cursor-based pagination.

Product lastSeenProduct = ...;

Product nextProduct =
    products.higher(lastSeenProduct);

This approach is useful when millions of records are continuously changing and offset pagination becomes slow.

TreeSet Performance Analysis

  • add() operation: O(log n)
  • remove() operation: O(log n)
  • contains() operation: O(log n)
  • first() operation: O(log n)
  • last() operation: O(log n)
  • Iteration: O(n)

Why TreeSet Is Better Than ArrayList Sorting

Suppose a product list has one million products. If you use ArrayList, every time a product changes you may need to sort the complete list again. TreeSet maintains ordering during insertion itself.

ArrayList Approach

Add Product
     |
     v
Store Object
     |
     v
Collections.sort()
     |
     v
Return Data


TreeSet Approach

Add Product
     |
     v
Insert at correct tree position
     |
     v
Already Sorted

Where Companies Use TreeSet

  • Product catalogs sorted by price or rating
  • Employee ranking systems
  • Scheduled events sorted by time
  • Report generation systems
  • Search result ordering
  • Financial report processing

Example: Event Scheduler Using TreeSet

A company scheduling platform needs to store upcoming meetings in chronological order. TreeSet is suitable because every event needs a unique position based on time.

TreeSet<LocalDateTime> meetings =
        new TreeSet<>();

meetings.add(LocalDateTime.now().plusHours(2));
meetings.add(LocalDateTime.now().plusHours(1));

System.out.println(meetings.first());

The application can instantly find the next scheduled event using first().

TreeSet Thread Safety Limitation

TreeSet is not thread-safe. This means multiple threads should not modify the same TreeSet instance at the same time without external synchronization.

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

Thread 1:
numbers.add(100);

Thread 2:
numbers.remove(50);

If multiple threads perform operations simultaneously, the internal Red-Black Tree structure may become inconsistent.

Making TreeSet Thread Safe

Set<Integer> synchronizedSet =
    Collections.synchronizedSet(
        new TreeSet<>()
    );

Collections.synchronizedSet adds synchronization around operations. However, it locks the complete collection, which can reduce performance when many threads access it.

TreeSet vs ConcurrentSkipListSet Decision

Real Enterprise Architecture Example

A large e-commerce platform usually keeps the database as the main source of truth. TreeSet is commonly used inside service logic for temporary sorting and processing.

Database
   |
   v
Repository Layer
   |
   v
Service Layer
   |
   v
TreeSet Processing
   |
   v
Controller
   |
   v
Customer

TreeSet Common Mistakes

  • Using TreeSet with objects that do not implement Comparable
  • Creating Comparator that returns zero for different objects
  • Changing object fields after inserting into TreeSet
  • Using TreeSet when multiple threads modify shared data
  • Expecting TreeSet to maintain insertion order

Changing Object After Insertion Problem

TreeSet depends on ordering. If an object field used in comparison changes after insertion, the tree structure may no longer represent the correct order.

Product p = new Product(1,"Laptop",50000);

products.add(p);

p.setPrice(10000);

The TreeSet does not automatically reorganize itself after the object's value changes. In enterprise applications, objects stored in sorted collections are usually immutable.

Future Scope of TreeSet in Modern Applications

Although modern systems use databases, caches, and distributed systems, TreeSet remains useful for local business processing where sorted unique data is required.

  • Pricing engines
  • Recommendation systems
  • Report generation
  • Scheduling algorithms
  • Rule engines
  • Data transformation pipelines

Advanced Future Use Case: Pricing Engine

Online shopping systems often have pricing rules. Products may need to be evaluated based on price ranges, discounts, and availability. A TreeSet can maintain products in sorted order while the pricing service processes rules.

Product Pricing Service
          |
          v
Sorted Products
          |
          v
Find cheapest eligible product
          |
          v
Apply Discount Rule
          |
          v
Return Final Price

TreeSet Interview Questions

  • How does TreeSet maintain sorting internally?
  • Which data structure does TreeSet use internally?
  • Why does TreeSet not allow duplicates?
  • What happens if Comparator returns zero?
  • Difference between TreeSet and HashSet?
  • Difference between Comparable and Comparator?
  • Is TreeSet thread-safe?
  • How does TreeSet achieve O(log n) complexity?

Final Summary

  • TreeSet stores unique elements in sorted order
  • TreeSet internally uses TreeMap and Red-Black Tree
  • Sorting is controlled by Comparable or Comparator
  • Comparator returning zero means duplicate element
  • Use thenComparing with unique fields for enterprise objects
  • TreeSet provides powerful navigation operations
  • TreeSet is not thread-safe
  • Use TreeSet for local sorted processing
  • Use ConcurrentSkipListSet for shared concurrent sorted data

TreeSet remains an important Java collection for enterprise development because it solves a common business problem: maintaining unique sorted data efficiently. Understanding its internal working helps developers design better systems and choose the correct collection for production requirements.