1. Overview
In this article, we will learn about the Java TreeSet with an example. TreeSet extends AbstractSet and implements the NavigableSet interface.
To learn about Java collections, refer to this article.
2. Java TreeSet
A TreeSet creates a collection that uses a tree for storage. It stores the elements in sorted, ascending order and prevents any duplicates. Access and retrieval times are quite fast, which makes the TreeSet an excellent choice when storing large amounts of sorted information that must be retrieved quickly.
It works just like the Collections.sort
method.
A TreeSet is similar to HashSet in that:
- Prevents duplicates
- Keeps the list sorted automatically
- Does not accept null values
The downside to TreeSet
is that if you don’t need sorting, you’re still paying for it with a small performance hit. But you’ll probably find that the hit is almost impossible to notice for most apps.
2.1. Java TreeSet constructors
A TreeSet is a generic class that has this declaration:
Class TreeSet<E>
Here, E specifies the type of objects that the set will hold.
A TreeSet has the following constructors:
TreeSet( ) TreeSet(Collection c) TreeSet(Comparator comp) TreeSet(SortedSet ss)2.2. Java TreeSet Sorting order
By default, the TreeSet uses each object’s
compareTo
method for the sort. But you have the option of passing aComparator
to theTreeSet
constructor, to have the TreeSet use that instead.To use a
TreeSet
, one of these things must be true:
- The elements in the list must be of a type that implements
Comparable
.- Specify the comparator as an argument to the TreeSet’s overloaded constructor
For example, the following code adds the
Employee
elements to theTreeSet
. Since theEmployee
class is not implementing the comparable, this won’t work.@Test void treeSetEmployeeExample() { TreeSet<Student> treeSet = new TreeSet<Student>(); treeSet.add(new Student(11020, "John", 99)); treeSet.add(new Student(11023, "Kevin", 84)); treeSet.add(new Student(11025, "Chris", 43)); treeSet.add(new Student(11029, "Elvis", 23)); treeSet.add(new Student(11030, "John", 78)); System.out.println(treeSet); } class Student { private long studentId; private String studentName; private int marks; Student(long studentId, String studentName, int marks) { this.studentId = studentId; this.studentName = studentName; this.marks = marks; } }If you execute the above code, it results in the
ClassCastException
.java.lang.ClassCastException: class com.tedblob.interview.InterviewApplicationTests$Student cannot be cast to class java.lang.Comparable (com.tedblob.interview.InterviewApplicationTests$Student is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap') at java.base/java.util.TreeMap.compare(TreeMap.java:1563)You can prevent this by either implementing a
Comparable
interface.class Student implements Comparable { private long studentId; private String studentName; private int marks; Student(long studentId, String studentName, int marks) { this.studentId = studentId; this.studentName = studentName; this.marks = marks; } @Override public int compareTo(Object o) { Student obj = (Student) o; return compare(this.marks, obj.marks); } private int compare(int thisObj, int obj) { return (thisObj < obj) ? 1 : ((thisObj == obj) ? 0 : -1); } @Override public String toString() { return "Student{" + "studentId=" + studentId + ", studentName='" + studentName + '\'' + ", marks=" + marks + '}'; } }Alternatively, you can pass a Comparator to the TreeSet overloaded constructor.
TreeSet<Student> treeSet = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { return (o1.getMarks() < o2.getMarks()) ? 1 : ((o1.getMarks() == o2.getMarks()) ? 0 : -1); } });3. Java TreeSet String example
Look at the following example. We have created an empty
TreeSet
with the default no-arg constructor. Later, pushed the elements to it using theadd
method.@Test void treeSetStringExample() { TreeSet<String> treeSet = new TreeSet<String>(); treeSet.add("Z"); treeSet.add("B"); treeSet.add("S"); treeSet.add("A"); treeSet.add("E"); treeSet.add("G"); System.out.println(treeSet); }If you execute the above test case, it prints the elements in ascending order.
[A, B, E, G, S, Z]It worked because the Java String implements the
Comparable
interface and itscompareTo
method.4. Java TreeSet prevents duplicates
Since the TreeSet is an implementation of the
Set
interface, it prevents duplicates.Look at the below code. Though we added the same element
"A"
twice, it appears only once.@Test void treeSetStringExample() { TreeSet<String> treeSet = new TreeSet<String>(); treeSet.add("A"); treeSet.add("A"); System.out.println(treeSet); }5. Java TreeSet with null
As mentioned earlier, a TreeSet cannot accept null values.
@Test void treeSetWithNullExample() { TreeSet<String> treeSet = new TreeSet<String>(); treeSet.add("Z"); treeSet.add(null); }By default, the Comparable interface is used internally by the TreeSet to sort the elements. Now in the Comparable Interface, the compareTo() method is used to compare one value with another to sort the elements.
So because of this purpose, null has no value, that’s why the compareTo() method cannot compare null with another value, giving a NullPointerException.
java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:208) at java.base/java.util.TreeMap.put(TreeMap.java:801) at java.base/java.util.TreeMap.put(TreeMap.java:534) at java.base/java.util.TreeSet.add(TreeSet.java:255)However, you can change this behavior by using a custom comparator that handles the
null
values. Once you handlenull
in the comparator, theTreeSet
won’t throwNullPointerException
.@Test void treeSetWithNullExample() { TreeSet<String> treeSet = new TreeSet<String>(new Comparator<String>() { @Override public int compare(String o1, String o2) { if (o1 == null) return 1; if (o2 == null) return -1; return o1.compareTo(o2); } }); treeSet.add("Z"); treeSet.add(null); System.out.println(treeSet); }If you execute the above test case, it shows the following output.
[Z, null]6. Conclusion
To sum up, we have learned the Java TreeSet along with an example. You can find code samples in our GitHub repository.