Comparable vs Comparator in java

Both Comparable and Comparator interfaces are used to perform sorting operation on collection of objects. Java also provide few in-build methods to sort array of primitive types or array/list of Wrapper class elements. But when it comes to the sorting of custom class objects then java.lang.Comparable and java.util.Comparator interfaces are used.

Example: sort array of primitive types and list of String objects

import java.util.*; 
public class Main {  
 
    public static void main(String args[]) 
    { 
        //Creating array of Primitive Type
        int[] intArray = {15,93,10,50, 44};
 
        //Print array elements
        System.out.println("Int Array before sorting: " + Arrays.toString(intArray));
 
        //Sorting array elements
        Arrays.sort(intArray);
 
        //Print array elements
        System.out.println("Int Array after sorting: " + Arrays.toString(intArray));
 
        //Creating String array
        String[] strArray = {"java", "c", "php", "oracle", "sql"};
 
        //Print array elements
        System.out.println("String Array before sorting: " + Arrays.toString(strArray));
 
        //Sorting array elements
        Arrays.sort(strArray);
 
        //Print array elements
        System.out.println("String Array after sorting: " + Arrays.toString(strArray));
 
        //Creating list of Wrapper class objects
        List<String> strList = new ArrayList<>();
 
        //Adding elements to list
        strList.add("java");
        strList.add("c");
        strList.add("php");
        strList.add("oracle");
        strList.add("sql");
 
        //Print array elements
        System.out.println("String List before sorting: " + strList);
 
        //Sorting list elements
        Collections.sort(strList);
 
        //Print array elements
        System.out.println("String List after sorting: " + strList);
    }  
}

Output

Int Array before sorting: [15, 93, 10, 50, 44]
Int Array after sorting: [10, 15, 44, 50, 93]
String Array before sorting: [java, c, php, oracle, sql]
String Array after sorting: [c, java, oracle, php, sql]
String List before sorting: [java, c, php, oracle, sql]
String List after sorting: [c, java, oracle, php, sql]

Let us try to sort list of custom objects.

import java.util.*; 
 
class Student {
    private int id;
    private String name;
    private int age;
 
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
 
    public int getId() {
        return id;
    }
 
    public String getName() {
        return name;
    }
 
    public int getAge() {
        return age;
    }
 
    @Override
    //Override toString method to return Student details
    public String toString() {
        return "[id=" + this.id + ", name=" + this.name + ", age=" + this.age +"]";
    }
 
}
 
public class Main {  
 
    public static void main(String args[]) 
    { 
        //Creating Student list
        ArrayList<Student> stuList = new ArrayList<Student>(); 
 
        //Adding Student elements
        stuList.add(new Student(1, "Himanshi", 32));
        stuList.add(new Student(4, "Amani", 33));
        stuList.add(new Student(3, "Swati", 33));
        stuList.add(new Student(2, "Prabhjot", 31));
 
        //Print array elements
        System.out.println("List before sorting: ");
        for(Student student : stuList){  
            System.out.println(student);  
        }  
 
        //Sorting list elements
        Collections.sort(stuList);  
 
        //Print array elements
        System.out.println("List after sorting: ");
        for(Student student : stuList){  
            System.out.println(student);  
        } 
    }  
}

Output

Main.java:54: error: no suitable method found for sort(ArrayList)
        Collections.sort(stuList);  
                   ^
    method Collections.<T#1>sort(List<T#1>) is not applicable
      (inference variable T#1 has incompatible bounds
        equality constraints: Student
        upper bounds: Comparable<? super T#1>)
    method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable
      (cannot infer type-variable(s) T#2
        (actual and formal argument lists differ in length))
  where T#1,T#2 are type-variables:
    T#1 extends Comparable<? super T#1> declared in method <T#1>sort(List<T#1>)
    T#2 extends Object declared in method <T#2>sort(List<T#2>,Comparator<? super T#2>)
1 error

Comparable interface:

Comparable interface can be used for sorting operation on custom objects collection, which is defined in java.lang package. It has only one method that is compareTo(Object o). It returns a negative int value, zero, or a positive int value if “this” i.e. current object is less than, equal to, or greater than the object passed as an parameter/argument.

Wrapper classes and String implements Comparable interface.

Note: By implementing Comparable interface, we can have default sorting and we can not change it dynamically. For example, in below code we have done the sorting based on student id and if we want to sort the elements based on student name then we can not do it.

Above example with the implementation of Comparable Interface.

import java.util.*; 
 
class Student implements Comparable<Student> {
    private int id;
    private String name;
    private int age;
 
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
 
    public int getId() {
        return id;
    }
 
    public String getName() {
        return name;
    }
 
    public int getAge() {
        return age;
    }
 
    @Override
    //Override compareTo method to customizing sorting algorithm
    public int compareTo(Student stu) {
        return (this.id - stu.id);
    }
 
    @Override
    //Override toString method to return Student details
    public String toString() {
        return "[id=" + this.id + ", name=" + this.name + ", age=" + this.age +"]";
    }
 
}
 
public class Main {  
 
    public static void main(String args[]) 
    { 
        //Creating Student list
        ArrayList<Student> stuList = new ArrayList<Student>(); 
 
        //Adding Student elements
        stuList.add(new Student(1, "Himanshi", 32));
        stuList.add(new Student(4, "Amani", 33));
        stuList.add(new Student(3, "Swati", 33));
        stuList.add(new Student(2, "Prabhjot", 31));
 
        //Print array elements
        System.out.println("List before sorting: ");
        for(Student student : stuList){  
            System.out.println(student);  
        }  
 
        //Sorting list elements
        Collections.sort(stuList);  
 
        //Print array elements
        System.out.println("List after sorting: ");
        for(Student student : stuList){  
            System.out.println(student);  
        } 
    }  
}

Output

List before sorting:
[id=4, name=Amani, age=33]
[id=3, name=Swati, age=33]
[id=2, name=Prabhjot, age=31] 
List after sorting: 
[id=1, name=Himanshi, age=32]  
[id=2, name=Prabhjot, age=31] 
[id=3, name=Swati, age=33]
[id=4, name=Amani, age=33]

Comparator interface:

Like Comparable interface, Comparator interface also used to sort a collection of custom objects and it is defined in java.util package. Its compare(Object obj1,Object obj2) method have to be implemented. The compare(Object obj1,Object obj2) method have to implemented in such a way that it will return a negative int value, zero, or a positive int value if first object/argument is less than, equal to, or greater than the second object/argument.

Note: It provides the mechanism to change the default sorting mechanism dynamically.

import java.util.*; 
import java.io.*;  
 
class Student {
    private int id;
    private String name;
    private int age;
 
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
 
    public int getId() {
        return id;
    }
 
    public String getName() {
        return name;
    }
 
    public int getAge() {
        return age;
    }
 
    //Compare based on id
    public static Comparator<Student> IdComparator = new Comparator<Student>() {
 
        @Override
        public int compare(Student stu1, Student stu2) {
            return (int) (stu1.getId() - stu2.getId());
        }
    };
 
    //Compare based on name
    public static Comparator<Student> NameComparator = new Comparator<Student>() {
 
        @Override
        public int compare(Student stu1, Student stu2) {
            return stu1.getName().compareTo(stu2.getName());
        }
    };
 
    @Override
    //Override toString method to return Student details
    public String toString() {
        return "[id=" + this.id + ", name=" + this.name + ", age=" + this.age +"]";
    }
 
}
 
public class Main {  
 
    public static void main(String args[]) 
    { 
        //Creating Student list
        ArrayList<Student> stuList = new ArrayList<Student>(); 
 
        //Adding Student elements
        stuList.add(new Student(1, "Himanshi", 32));
        stuList.add(new Student(4, "Amani", 33));
        stuList.add(new Student(3, "Swati", 33));
        stuList.add(new Student(2, "Prabhjot", 31));
 
        //Print array elements
        System.out.println("List before sorting: ");
        for(Student student : stuList){  
            System.out.println(student);  
        }  
 
        //Sorting list elements by Student Id
        Collections.sort(stuList, Student.IdComparator);  
 
        //Print array elements
        System.out.println("List after sorting by Student Id: ");
        for(Student student : stuList){  
            System.out.println(student);  
        } 
 
        //Sorting list elements by Student Name
        Collections.sort(stuList, Student.NameComparator);  
 
        //Print array elements
        System.out.println("List after sorting by Student Name: ");
        for(Student student : stuList){  
            System.out.println(student);  
        } 
    }  
}

Output

List before sorting:
[id=1, name=Himanshi, age=32]
[id=4, name=Amani, age=33]
[id=3, name=Swati, age=33]
[id=2, name=Prabhjot, age=31] 
List after sorting by Student Id:
[id=1, name=Himanshi, age=32]
[id=2, name=Prabhjot, age=31]
[id=3, name=Swati, age=33]
[id=4, name=Amani, age=33]
List after sorting by Student Name: 
[id=4, name=Amani, age=33]
[id=1, name=Himanshi, age=32]
[id=2, name=Prabhjot, age=31]
[id=3, name=Swati, age=33]

 

Difference between Comparable and Comparator in Java

Comparable Comparator
It provides only default or one sort of sequence and we can not change it dynamically. It provides multiple sort of sequences and we can change sort sequence dynamically.
It provides compareTo() method to be implemented for sorting mechanism. It provides compare() method to be implemented for sorting mechanism.
It is in java.lang package. it is in java.util package.
If we implement Comparable interface, actual class is modified. Actual class is can or can not be modified. It depends upon how we have implemented Comparator interface. In the above implementation we have to modify our actual class but if we implement Comparator as an separate class comparators then there will not be any change in actual class. See the below example as a reference of student name comparator as a separate class.
import java.util.*;  
class NameComparator implements Comparator<Student>{  
  public int compare(Student stu1,Student stu2){  
     return stu1.name.compareTo(stu2.name);  
  }  
}

 

Java interview questions on collections