Java
TreeSet
k-th element
programming
data structures

How to return the k-th element in TreeSet in Java?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

TreeSet keeps elements sorted, but it is still a set, not an indexed list. That means there is no built-in get(k) method, so finding the k-th element requires either iteration, a temporary list, or a different data structure if indexed access is a core requirement.

Why TreeSet Has No Positional Access

TreeSet is backed by a balanced tree and optimized for ordered set operations such as insert, remove, first, last, higher, and lower. Those operations are efficient because the structure maintains sorted order, but it does not track element positions the way ArrayList does.

If you want the third smallest element, Java cannot jump directly to it by index. The simplest approach is to iterate until you reach the desired position.

java
1import java.util.Iterator;
2import java.util.TreeSet;
3
4public class Main {
5    public static Integer kthElement(TreeSet<Integer> set, int k) {
6        if (k < 0 || k >= set.size()) {
7            throw new IndexOutOfBoundsException("k out of range");
8        }
9
10        Iterator<Integer> iterator = set.iterator();
11        for (int i = 0; i < k; i++) {
12            iterator.next();
13        }
14        return iterator.next();
15    }
16
17    public static void main(String[] args) {
18        TreeSet<Integer> numbers = new TreeSet<>();
19        numbers.add(40);
20        numbers.add(10);
21        numbers.add(30);
22        numbers.add(20);
23
24        System.out.println(kthElement(numbers, 2)); // 30
25    }
26}

This is an O(k) walk through the sorted set. For occasional lookups, that is usually fine.

Convert to a List When Repeated Access Matters

If you need several indexed lookups from the same snapshot, converting once to a list is often clearer.

java
1import java.util.ArrayList;
2import java.util.List;
3import java.util.TreeSet;
4
5public class Main {
6    public static void main(String[] args) {
7        TreeSet<String> names = new TreeSet<>();
8        names.add("Rita");
9        names.add("Ana");
10        names.add("Leo");
11
12        List<String> ordered = new ArrayList<>(names);
13        System.out.println(ordered.get(1)); // Leo
14    }
15}

This approach costs O(n) to build the list, but subsequent indexed reads are constant time. It is a good tradeoff when you already need list semantics for presentation, paging, or testing.

Streams Are Concise but Not Faster

Java streams can make the code compact:

java
1import java.util.TreeSet;
2
3public class Main {
4    public static void main(String[] args) {
5        TreeSet<Integer> set = new TreeSet<>();
6        set.add(5);
7        set.add(15);
8        set.add(25);
9
10        Integer value = set.stream()
11            .skip(1)
12            .findFirst()
13            .orElseThrow();
14
15        System.out.println(value); // 15
16    }
17}

This still walks the set until the desired position. It is mostly a stylistic alternative to iterator-based code, not a different complexity class.

Pick a Different Structure for Heavy Indexed Reads

If your real requirement is "sorted collection with fast k-th lookup," TreeSet is the wrong abstraction. You might keep data in a sorted ArrayList, use a specialized order-statistics tree from a third-party library, or redesign the algorithm so it does not require repeated positional access into a set.

That design choice matters more than micro-optimizing iterator code. A clean TreeSet solution is good for occasional retrieval. A workload with thousands of k-th element lookups usually deserves a different container.

Common Pitfalls

  • Mixing zero-based and one-based indexing. In Java code, k = 0 should usually mean the first element.
  • Forgetting bounds checks before iterating. Empty sets and oversized k values should fail clearly.
  • Assuming streams make the operation faster. They still traverse elements in order.
  • Rebuilding a list for every lookup. If you need many indexed reads, convert once and reuse it.
  • Modifying the set while iterating, which can trigger ConcurrentModificationException.

Summary

  • 'TreeSet is ordered, but it does not support direct indexed access.'
  • Use an iterator when you only need the k-th element occasionally.
  • Convert to a list when you need several indexed reads from the same sorted snapshot.
  • Streams can express the lookup cleanly, but they do not change the underlying cost.
  • If k-th lookup is a primary operation, choose a data structure designed for it.

Course illustration
Course illustration

All Rights Reserved.