TreeSet class in Java is part of Java’s collections framework which implements the NavigableSet interface, which provides functionalities to navigate through the SortedSet. The NavigableSet further extends the SortedSet interface, which provides functionalities to keep the elements sorted.
As the TreeSet class implements a NavigableSet interface, it has features of both – the NavigableSet and the SortedSet.
The TreeSet sort or orders the elements according to the natural ordering. All the Wrapper classes and the String class already implements Comparable interface. But in the case of custom objects, one has to implement Comparable or Comparator interfaces in the corresponding class, so that TreeSet can sort the objects as we desire.
TreeSet with user-defined objects
An object is said to be comparable if and only if the corresponding class implements Comparable or Comparator interface. The compare() method of Comparator interface and compareTo() method of Comparable interface provide the sorting logic to TreeSet, which enables the TreeSet to insert values accordingly. Now, if you want to avoid any duplicate entry of objects in TreeSet, you have to implement these interfaces with equality verification. And we can do this in multiple ways,
Example:
1. Using the comparable interface: Let us make a student class, Student, that includes student name and the rank of student in any course. Here, no more than one student can have the same rank. So, if made a new entry of any student with a rank that is previously occupied by another student, then that entry would be a duplicate entry. Otherwise, the student will be sorted on the basis of its name in ascending order.
Override compareTo() method to provide the sorting logic. In the compareTo() method of the Comparable interface, we first check whether the ranks of the two student objects are the same, if they are the same, then return 0, which means the two objects are the same. Else, if the rank isn’t the same, compare the names of the student objects and return 1 or -1 accordingly.
Java
// Java Program to Avoid Duplicate User // Defined Objects in TreeSet import java.util.*; // implementing comparable interface public class Student implements Comparable<Student> { private String name; private int rank; // constructor Student(String name, int rank) { this .name = name; this .rank = rank; } // returns the student name private String getName() { return name; } // returns student rank public int getRank() { return rank; } /* overriding compareTo() method. if the object has same rank then it is considered as a duplicate entry, else, the entry is sorted on the basis of the student name. */ @Override public int compareTo(Student o) { if (rank == o.getRank()) { return 0 ; } else if (name.compareTo(o.getName()) < 0 ) { return - 1 ; } else return 1 ; } // overriding toString() to print the student detail @Override public String toString() { return name + " (" + rank + ")" ; } } // driver class class Gfg { public static void main(String args[]) { // create a TreeSet which stores objects of type // Student TreeSet<Student> students = new TreeSet<>(); // add objects to the TreeSet students.add( new Student( "Raghav" , 12 )); students.add( new Student( "Tilak" , 11 )); // adding an object with same rank students.add( new Student( "Ayush" , 12 )); // adding an object with same name but different // rank students.add( new Student( "Raghav" , 32 )); // print the TreeSet for (Student s : students) { System.out.println(s); } } } |
Raghav (12) Raghav (32) Tilak (11)
2. Using the comparator interface: Let us make a class Employee that has employee name and employee id. Here, no two or more employees can have the same ids. And the employees are sorted on the basis of their ids. (We can implement the same logic as above in this method also). While using Comparator, pass the instance of the comparator in the constructor of the TreeSet while creating one. This ensures that TreeSet is ordered in the way we desire and not by the natural ordering used by the TreeSet.
Java
// Java Program to Avoid Duplicate User // Defined Objects in TreeSet import java.util.*; // implementing comparator interface public class Employee implements Comparator<Employee> { private String name; private int id; // constructor public Employee(String name, int id) { this .name = name; this .id = id; } // default constructor is required, since we have to // pass the instance of Comparator in the constructor, // while creating a TreeSet public Employee() {} // returns employee name public String getName() { return name; } // returns id of the employee public int getId() { return id; } /* overriding the compare() method, this method compare two objects of type Employee on the basis of their id, if the ids of two employees is same then its considered a duplicate entry. else, it is sorted of the basis of id. */ @Override public int compare(Employee emp1, Employee emp2) { if (emp1.getId() == emp2.getId()) { return 0 ; } else if (emp1.getId() < emp2.getId()) { return - 1 ; } else { return 1 ; } } // overriding toString() to print the employee detail @Override public String toString() { return name + " (" + id + ")" ; } } // driver class class Gfg { public static void main(String args[]) { // create a TreeSet which stores objects of type // Employee TreeSet<Employee> employees = new TreeSet<>( new Employee()); // add objects to the TreeSet employees.add( new Employee( "Raghav" , 934 )); employees.add( new Employee( "Tilak" , 435 )); employees.add( new Employee( "Mumukshi" , 252 )); // adding an object with same id employees.add( new Employee( "Shalu" , 934 )); // printing the TreeSet for (Employee s : employees) { System.out.println(s); } } } |
Mumukshi (252) Tilak (435) Raghav (934)