Friday, 8 March 2019

How Comparable and Comparator works internally in Java

How Comparable and Comparator works internally in Java 


In Java, Comparable and Comparator are used for sorting collection of objects.

java.lang.Comparable is used to sort collection of same types(classes) like List<Student>, List<Employee>, List<Orange>, It means Comparable is like "I can compare myself with another object of same type".

Example: if we want to sort List<Student> based on roll number or their first name etc.

java.util.Comparator is used to sort collection of different types(classes) like List<Object>.
It means Comparator is like "I can compare myself with other object of same/different type"

If you have observe java.util.Comparator is more like a Utility class that can sort objects of any class you provide and that is why it is in util package. 


Comparable example


package com.javabypatel;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ComparableExample {

    private static final int INSERTIONSORT_THRESHOLD = 7;

    public static void main(String[] args) {
        Student s1 = new Student(10);
        Student s2 = new Student(50);
        Student s3 = new Student(20);
        Student s4 = new Student(30);

        List<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);
        System.out.println("Before sort:");
        list.forEach(s -> System.out.print(s.rollNo + " "));

        sort(list);
        //Collections.sort(list);

        System.out.println("After sort:");
        list.forEach(s -> System.out.print(s.rollNo + " "));
    }

    static void sort(List<Student> list) {
        int low = 0;
        Object[] dest = list.toArray();
        for (int i = 0; i < list.size(); i++)
            for (int j = i; j > low && ((Comparable) dest[j - 1]).compareTo(dest[j]) > 0; j--)
                swap(dest, j, j - 1);

        ListIterator<Student> i = list.listIterator();
        for (Object e : dest) {
            i.next();
            i.set((Student) e);
        }
    }

    private static void swap(Object[] x, int a, int b) {
        Object t = x[a];
        x[a] = x[b];
        x[b] = t;
    }

}

class Student implements Comparable<Student>{
    int rollNo;

    public Student(int rollNo) {
        this.rollNo = rollNo;
    }

    @Override
    public int compareTo(Student s) {
        if(rollNo==s.rollNo)
            return 0;
        else if(rollNo>s.rollNo)
            return 1;
        else
            return -1;
    }
}


Output:

Before sort:
10 50 20 30
After sort:
10 20 30 50

Here we are sorting List of Students by their roll number.
Generally we should be using "Collections.sort(list);" for sorting the list, for better understanding I have copied the code of sort method to understand how internally it sort the list.

It compare 2 objects and swap based on result returned by compareTo method.

Comparator example


package com.javabypatel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparatorExample {

    public static void main(String[] args) {
        Student s1 = new Student(10, "Zara");
        Student s2 = new Student(50, "Jayesh");
        Student s3 = new Student(20, "Ash");
        Student s4 = new Student(30, "Kate");

        List<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);

        System.out.println("Before sort:");
        list.forEach(s -> System.out.print(s.name + " " + s.rollNo + ", "));

        NameComparator nameComparator = new NameComparator();
        Collections.sort(list, nameComparator);

        System.out.println("\n\nAfter sort by name:");
        list.forEach(s -> System.out.print(s.name + " " + s.rollNo + ", "));

        RollNumberComparator rollNumberComparator = new RollNumberComparator();
        Collections.sort(list, rollNumberComparator);

        System.out.println("\n\nAfter sort by Roll number:");
        list.forEach(s -> System.out.print(s.name + " " + s.rollNo + ", "));
    }
}


package com.javabypatel;

import java.util.Comparator;

public class Student {
    int rollNo;
    String name;

    public Student(int rollNo, String name) {
        this.rollNo = rollNo;
        this.name = name;
    }
}


//Name Comparator
class NameComparator implements Comparator<Student> {
    public int compare(Student s1, Student s2) {
        return s1.name.compareTo(s2.name);
    }
}

//Roll number Comparator 
class RollNumberComparator implements Comparator<Student> {
    public int compare(Student s1, Student s2) {
        if (s1.rollNo < s2.rollNo) return -1;
        if (s1.rollNo > s2.rollNo) return 1;
        else return 0;
    }
} 

Output: 
Before sort: 
Zara 10, Jayesh 50, Ash 20, Kate 30, 

After sort by name: 
Ash 20, Jayesh 50, Kate 30, Zara 10, 

After sort by Roll number: 
Zara 10, Ash 20, Kate 30, Jayesh 50,

You may also like to see


Level Order Traversal of Binary Tree.

Advanced Multithreading Interview Question-Answer

Traverse a Binary Tree in Level Order Traversal

Serialize and Deserialize a Binary Tree

Find diameter of Binary Tree

How Much Water Can a Bar Graph with different heights can Hold

Interview Question-Answer on Java

Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

No comments:

Post a Comment