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()andlast(). - Range views:
headSet(),tailSet()andsubSet(). - Comparator access:
comparator()returns the comparator, ornullfor natural order. - Elements must be mutually comparable, and duplicates are decided by comparison, not
equals().
2. Hierarchy and Declaration
public interface SortedSet<E> extends Set<E>, SequencedSet<E> // Java 21+
// before Java 21: public interface SortedSet<E> extends Set<E>
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:
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)");
}
}
Cities: [Agra, Delhi, Pune, Surat] first(): Agra last(): Surat comparator(): null (null = natural order)
4. SortedSet Methods
| Method | Description |
|---|---|
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:
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() + ")");
}
}
}
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
failedview. - A view rejects elements outside its range with
IllegalArgumentException.
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:
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));
}
}
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:
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();
}
}
Read-only view: [DEBUG, ERROR, INFO, WARN], first=DEBUG add(): UnsupportedOperationException DEBUG ERROR INFO WARN
8. Implementations
| Class | Structure | Thread-safe | Notes |
|---|---|---|---|
| TreeSet | Red-black tree | No | The usual choice; O(log n) operations. |
ConcurrentSkipListSet | Skip list | Yes | Sorted set for concurrent use, without global locking. |
Collections.unmodifiableSortedSet() | Wrapper | Read-only | A view that rejects changes. |
Collections.synchronizedSortedSet() | Wrapper | Yes (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.
| Need | SortedSet | NavigableSet |
|---|---|---|
| Smallest / largest | first(), last() | Same, plus pollFirst(), pollLast() |
| Nearest element | Not available | lower(), floor(), ceiling(), higher() |
| Range with chosen bounds | Lower inclusive, upper exclusive only | subSet(from, fromInclusive, to, toInclusive) |
| Reverse order | reversed() (Java 21) | descendingSet(), descendingIterator() |
10. Rules for Elements
- With natural ordering, elements must implement
Comparable; otherwise adding throwsClassCastException. nullis 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()andcomparator(). - 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
Frequently Asked Questions (FAQ)
Q1. What is a SortedSet in Java?
SortedSet is an interface in java.util that extends Set and keeps its elements in ascending order, by natural ordering or a comparator. It adds first(), last(), range views and comparator().
Q2. Which classes implement SortedSet?
TreeSet and ConcurrentSkipListSet, both through NavigableSet. The wrappers from Collections.unmodifiableSortedSet() and Collections.synchronizedSortedSet() also implement it.
Q3. Can I create a SortedSet object directly?
No, it is an interface. Write SortedSet<String> set = new TreeSet<>();.
Q4. What does comparator() return?
The Comparator used to order the set, or null if the set uses the elements' natural ordering.
Q5. Is headSet() inclusive or exclusive?
Exclusive: headSet(x) contains elements strictly less than x. tailSet(x) is inclusive: elements greater than or equal to x.
Q6. Are the sets returned by headSet(), tailSet() and subSet() copies?
No. They are views backed by the original set, so changes in either are visible in the other. Copy a view with new TreeSet<>(view) if you need an independent set.
Q7. What happens if I add an out-of-range element to a range view?
The view throws IllegalArgumentException, because the element would not belong to the view's range.
Q8. What happens when I call first() on an empty SortedSet?
It throws NoSuchElementException. Check isEmpty() first, or use pollFirst() from NavigableSet, which returns null.
Q9. Does SortedSet allow null?
Not with natural ordering. TreeSet throws NullPointerException when you add null. A comparator that handles null can technically allow it.
Q10. What is the difference between SortedSet and NavigableSet?
NavigableSet extends SortedSet. It adds lower(), floor(), ceiling(), higher(), pollFirst(), pollLast(), descendingSet() and range methods with explicit inclusive flags.
Q11. How does SortedSet decide two elements are duplicates?
By comparison: if compareTo() or the comparator returns 0, the elements are duplicates. equals() is not used.
Q12. How do I sort a SortedSet in descending order?
Create it with a reverse comparator: new TreeSet<>(Comparator.reverseOrder()). For an existing set, use reversed() (Java 21) or descendingSet() on a NavigableSet.
Q13. What is the difference between SortedSet and SortedMap?
A SortedSet stores sorted single elements; a SortedMap stores key–value pairs sorted by key. They have matching methods: first()/firstKey(), headSet()/headMap() and so on.
Q14. Is SortedSet thread-safe?
The interface itself says nothing about threads. TreeSet is not thread-safe; ConcurrentSkipListSet is. You can also wrap a TreeSet with Collections.synchronizedSortedSet().
Q15. What is the time complexity of SortedSet operations in a TreeSet?
add, remove, contains, first and last are O(log n). Creating a range view is O(log n) or better; counting its elements with size() is O(size of the range).
Q16. Can a SortedSet contain elements of different types?
Only if they can be compared with each other. Mixing Integer and String with natural ordering throws ClassCastException.
Q17. How do I get the elements of a SortedSet between two values, including both ends?
Use a NavigableSet: treeSet.subSet(from, true, to, true). With plain SortedSet methods you must pass the next value after to as the upper bound.
Q18. Which Java 21 methods does SortedSet support?
It extends SequencedSet, so it supports getFirst(), getLast(), removeFirst(), removeLast() and reversed(). addFirst() and addLast() throw UnsupportedOperationException, because a sorted set decides positions itself.
Q19. When should I use SortedSet as a variable type?
When your code only needs sorted iteration, endpoints and simple ranges. If you need nearest-value lookups or inclusive ranges, declare the variable as NavigableSet instead.
Q20. How do I convert a SortedSet to a list?
List<String> list = new ArrayList<>(sortedSet);
The list keeps the set's sorted order.