Java TreeSet: Explained With Examples

In this blog post you’ll read about what a Java TreeSet is and when to use it. Also, we’ll take a look at some examples that TreeSet in Java has to offer. It has quite a few different features from the HashSet.

What is Java TreeSet?

TreeSet in Java is a collection that implements from the NavigableSet interface. It is a sorted set in which by default the objects keep their natural ordering. We can also define a custom ordering for the TreeSet if needed. This is possible by providing a Comparator as a parameter into the constructor during the creation of the set. In the following example we create a TreeSet that sorts elements in the reversed ordering:

// Create set of numbers in the reversed ordering
Set<Integer> reversedNumbers = new TreeSet<>(Comparator.reverseOrder());

reversedNumbers.add(2);
reversedNumbers.add(0);
reversedNumbers.add(3);
reversedNumbers.add(1);

System.out.println("Numbers: " + reversedNumbers);

Output:

Numbers: [3, 2, 1, 0]

When we take a look at Treesets’ source code we can see that TreeSet is actually using a TreeMap under the hood. To point out, TreeMap is an implementation of a Red-Black tree.

public TreeSet() {
    this(new TreeMap<E,Object>());
}

Therefore TreeSets’ basic operations add, remove and contains have a guaranteed time cost of log(n).

To point out, TreeSet in Java is not synchronized. To achieve a synchronized set we can wrap it with Collections.synchronizedSortedSet method:

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

Also, TreeSet doesn’t allow duplicate elements similarly to the HashSet .

TreeSet has been available since JDK 1.2.

When to use Java TreeSet?

Simply put, use it when you need to keep objects in a sorted order in a set. Otherwise go for a HashSet as it has a time cost of O(1) for its’ basic operations which means it’s slightly faster.

How to use TreeSet in Java?

Java TreeSet offers several different methods from a HashSet. Lets’ take a look at some example code to get a better overview of those.

Creating a TreeSet

First, we’ll create a new TreeSet that will hold numbers in it. By default the set has elements in the natural ordering.

// Creating a new set
TreeSet<Integer> numbers = new TreeSet<>();

// Add some numbers in a random order
numbers.add(3);
numbers.add(0);
numbers.add(2);
numbers.add(1);

// Display what objects we have in the set
System.out.println("Numbers: " + numbers);

Output:

Numbers: [0, 1, 2, 3]

Subset of a TreeSet

We can also display a subset of the TreeSet. Subsets‘ first parameter (in our example 0) will be included in the returned set and the second parameter (in our example 2) will not be included.

// Display subset from 0 to 2
System.out.println("Subset: " + numbers.subSet(0, 2));

Output:

Subset: [0, 1]

First and last element of a TreeSet

We can also display a first and last element in the TreeSet by using the first and last method.

System.out.println("First: " + numbers.first());
System.out.println("Last: " + numbers.last());

Output:

First: 0
Last: 3

Ceiling and floor of an element in a TreeSets

Ceiling returns the least object that is greater than or equal to the given object. Otherwise it returns null if there is no such element in the set.

Floor returns the greatest object that is less than or equal to the given object. Otherwise null if no such element exists in the set.

System.out.println("Ceiling: " + numbers.ceiling(2));
System.out.println("Floor: " + numbers.floor(2));

Output:

Ceiling: 2
Floor: 2

Head and tail of an element in a Treesets

Head returns a set of elements that are less than the given object. Tail returns a set of elements that are equal or greater than the given object.

System.out.println("Head: " + numbers.headSet(2));
System.out.println("Tail: " + numbers.tailSet(2));

Output:

Head: [0, 1]
Tail: [2, 3]

Lower and higher element in a TreeSet

Lower returns the element that is less than the given element or null if the element does not exist in the set. Higher returns the greater element than the given element. Otherwise, it returns null.

System.out.println("Lower: " + numbers.lower(2));
System.out.println("Higher: " + numbers.higher(2));

Output:

Lower: 1
Higher: 3

Polling elements from a TreeSet

Polling elements is similar to removing elements from a TreeSet. The difference is that polling will also return the removed element. For polling we can use pollFirst and pollLast methods. pollFirst returns and removes the first element in the set. pollLast returns and removes the last element in the set.

System.out.println("Polled first: " + numbers.pollFirst());
System.out.println("Polled last: " + numbers.pollLast());

Output:

Polled first: 0
Polled last: 3

Remove element from a TreeSet

In addition to polling an element from a TreeSet we can also directly remove a desired element from a TreeSet. remove will return true when the element was removed from the set.

System.out.println("Removed: " + numbers.remove(2));

Output:

Removed: true

Conclusion

In this blog post we covered what a TreeSet is and went through some examples of its’ features. You could use a TreeSet when you need to have elements sorted in a set. Whether it is by the natural ordering or your own defined custom sorting. If no sorting is needed and there shouldn’t be duplicates in a collection you should just go for a HashSet.

Hope you found this blog post useful! Don’t forget to also subscribe to new blog posts if you find them useful 🙂

Be the first to reply

Leave a Reply

Your email address will not be published. Required fields are marked *