00:00

SortedSet Interface in Java – Guide with Examples

SortedSet is a Set whose elements are always kept in ascending order. Besides the normal set operations, it lets you ask for the first and last elements and take range views such as "all values below 50".

It is an interface in java.util, added in JDK 1.2. Its main implementation is TreeSet. This tutorial explains each SortedSet method with examples and shows how it relates to NavigableSet.

1. What Is a SortedSet?

A SortedSet guarantees one thing above an ordinary Set: its iterator returns elements in sorted order. The order comes either from the elements' natural ordering (Comparable) or from a Comparator given when the set is created.

  • Unique, sorted elements.
  • Endpoints: first() and last().
  • Range views: headSet(), tailSet() and subSet().
  • Comparator access: comparator() returns the comparator, or null for natural order.
  • Elements must be mutually comparable, and duplicates are decided by comparison, not equals().

2. Hierarchy and Declaration

java.util.SortedSet
public interface SortedSet<E> extends Set<E>, SequencedSet<E>   // Java 21+
// before Java 21: public interface SortedSet<E> extends Set<E>
Hierarchy
Collection
 └─ Set
     └─ SortedSet
         └─ NavigableSet
             ├─ TreeSet
             └─ ConcurrentSkipListSet

3. Creating and Using a SortedSet

Because SortedSet is an interface, create a TreeSet and store it in a SortedSet variable:

SortedSetBasics.java
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

public class SortedSetBasics {
    public static void main(String[] args) {
        SortedSet<String> cities = new TreeSet<>(List.of("Pune", "Agra", "Surat", "Delhi", "Agra"));

        System.out.println("Cities:       " + cities);
        System.out.println("first():      " + cities.first());
        System.out.println("last():       " + cities.last());
        System.out.println("comparator(): " + cities.comparator() + "  (null = natural order)");
    }
}
Output
Cities:       [Agra, Delhi, Pune, Surat]
first():      Agra
last():       Surat
comparator(): null  (null = natural order)

4. SortedSet Methods

MethodDescription
E first()The lowest element. Throws NoSuchElementException if the set is empty.
E last()The highest element. Throws NoSuchElementException if the set is empty.
SortedSet<E> headSet(E toElement)View of elements strictly less than toElement.
SortedSet<E> tailSet(E fromElement)View of elements greater than or equal to fromElement.
SortedSet<E> subSet(E from, E to)View of elements from from (included) to to (excluded).
Comparator<? super E> comparator()The comparator used, or null for natural ordering.
getFirst(), getLast(), removeFirst(), removeLast(), reversed()Sequenced methods added in Java 21. addFirst() and addLast() are not supported, because the position is decided by the sort order.

A SortedSet also has every method of Set and Collection, such as add(), remove(), contains() and size().

5. Range Views: headSet, tailSet and subSet

Range views make it easy to split sorted data into bands. Here exam marks are grouped into failed, passed and distinction:

SortedSetRanges.java
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

public class SortedSetRanges {
    public static void main(String[] args) {
        SortedSet<Integer> marks = new TreeSet<>(List.of(35, 48, 52, 67, 74, 81, 90, 99));

        SortedSet<Integer> failed = marks.headSet(50);        // < 50
        SortedSet<Integer> distinction = marks.tailSet(75);   // >= 75
        SortedSet<Integer> passed = marks.subSet(50, 75);     // 50 <= x < 75

        System.out.println("Failed (<50):        " + failed);
        System.out.println("Passed (50-74):      " + passed);
        System.out.println("Distinction (>=75):  " + distinction);

        // Views are live: changes to the original appear in them
        marks.add(41);
        System.out.println("After add(41), failed view: " + failed);

        // Adding outside the view's range is not allowed
        try {
            failed.add(60);
        } catch (IllegalArgumentException e) {
            System.out.println("failed.add(60): IllegalArgumentException (" + e.getMessage() + ")");
        }
    }
}
Output
Failed (<50):        [35, 48]
Passed (50-74):      [52, 67, 74]
Distinction (>=75):  [81, 90, 99]
After add(41), failed view: [35, 41, 48]
failed.add(60): IllegalArgumentException (key out of range)
  • The lower bound is inclusive and the upper bound is exclusive, like String.substring().
  • Views are live: the 41 added to the original set appeared in the failed view.
  • A view rejects elements outside its range with IllegalArgumentException.
Tip: to include the upper bound with a SortedSet, use the next possible value, for example subSet(50, 75 + 1) for integers. A NavigableSet has overloads with explicit inclusive flags, which are clearer.

6. Custom Order with a Comparator

Here tasks are sorted by highest priority first, with the name as a tie-breaker so that two tasks with the same priority are both kept:

SortedSetCustomOrder.java
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;

public class SortedSetCustomOrder {
    record Task(String name, int priority) { }

    public static void main(String[] args) {
        // Highest priority first, then by name
        Comparator<Task> order = Comparator.comparingInt(Task::priority).reversed()
                                           .thenComparing(Task::name);
        SortedSet<Task> tasks = new TreeSet<>(order);
        tasks.add(new Task("write tests", 2));
        tasks.add(new Task("fix outage", 5));
        tasks.add(new Task("code review", 2));
        tasks.add(new Task("update docs", 1));

        tasks.forEach(t -> System.out.println(t.priority() + "  " + t.name()));
        System.out.println("Most urgent: " + tasks.first().name());
        System.out.println("Uses a custom comparator? " + (tasks.comparator() != null));
    }
}
Output
5  fix outage
2  code review
2  write tests
1  update docs
Most urgent: fix outage
Uses a custom comparator? true

7. Read-Only and Synchronized SortedSets

The Collections class provides wrappers that keep the SortedSet type:

ReadOnlySortedSet.java
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

public class ReadOnlySortedSet {
    public static void main(String[] args) {
        SortedSet<String> levels = new TreeSet<>(List.of("DEBUG", "ERROR", "INFO", "WARN"));
        SortedSet<String> readOnly = Collections.unmodifiableSortedSet(levels);

        System.out.println("Read-only view: " + readOnly + ", first=" + readOnly.first());
        try {
            readOnly.add("TRACE");
        } catch (UnsupportedOperationException e) {
            System.out.println("add(): UnsupportedOperationException");
        }

        SortedSet<String> shared = Collections.synchronizedSortedSet(new TreeSet<>(levels));
        synchronized (shared) {                 // lock while iterating
            for (String s : shared) System.out.print(s + " ");
        }
        System.out.println();
    }
}
Output
Read-only view: [DEBUG, ERROR, INFO, WARN], first=DEBUG
add(): UnsupportedOperationException
DEBUG ERROR INFO WARN

8. Implementations

ClassStructureThread-safeNotes
TreeSetRed-black treeNoThe usual choice; O(log n) operations.
ConcurrentSkipListSetSkip listYesSorted set for concurrent use, without global locking.
Collections.unmodifiableSortedSet()WrapperRead-onlyA view that rejects changes.
Collections.synchronizedSortedSet()WrapperYes (locks)Lock it manually while iterating.

9. SortedSet vs NavigableSet

NavigableSet (Java 6) extends SortedSet with more precise navigation. New code usually declares variables as NavigableSet or uses TreeSet directly to get these extra methods.

NeedSortedSetNavigableSet
Smallest / largestfirst(), last()Same, plus pollFirst(), pollLast()
Nearest elementNot availablelower(), floor(), ceiling(), higher()
Range with chosen boundsLower inclusive, upper exclusive onlysubSet(from, fromInclusive, to, toInclusive)
Reverse orderreversed() (Java 21)descendingSet(), descendingIterator()

10. Rules for Elements

  • With natural ordering, elements must implement Comparable; otherwise adding throws ClassCastException.
  • null is not allowed with natural ordering.
  • Two elements that compare as 0 are duplicates, even if equals() says otherwise.
  • The ordering should be consistent with equals so the set behaves like a normal Set.
  • Do not change fields used for ordering while the element is in the set.

11. Summary

  • SortedSet is a Set that keeps elements in ascending order.
  • It adds first(), last(), headSet(), tailSet(), subSet() and comparator().
  • Range views are live, inclusive at the start and exclusive at the end.
  • TreeSet is the main implementation; ConcurrentSkipListSet is the thread-safe one.
  • NavigableSet extends SortedSet with nearest-element and flexible-range methods.

Related Tutorials

Reference: Java SE 21 API: java.util.SortedSet