Sunday, August 21, 2011

Usage of generics in comparable and comparator interface

Generics provides with type safety for parameters and catches type checking error at compile time instead of runtime.
Comparable interface is used when two instance of same object needs to compare and comparator interface is used if object that doesn't implement
comparable interface or to compare objects using different ordering. Generally, we call ordering done by comparable interface as natural ordering
and ordering done by comparator interface as unnatural ordering.

Comparable Interface :
If a class is implementing a comparable interface as in below example, it can compare any type of object rather than object of type class or before
comparison, we need to check type of object and then cast an object to that type and then perform comparison.
For e.g.
public class Employee implements Comparable {
String empName;
Integer empId;
Integer age;
public static void main(String[] args) {
Employee empOne = new Employee();
empOne.empName = "Raj";
empOne.empId = 1;
empOne.age = 45;
ComparableTest cmpOne = new ComparableTest();
cmpOne.name = "Raj";
cmpOne.age = 45;
if(empOne.compareTo(cmpOne) == 1) {
System.out.println("Equal Object");
} else {
System.out.println("Unequal Object");
}
}
@Override
public int compareTo(Object o) {
if(o instanceof Employee/*if this check is not perform then code will throw run time error*/ && this.age.equals(((Employee)o).age)) {
return 1;
}
return 0;
}
}
Now example using generics.
public class Employee implements Comparable&ltEmployee> {
String empName;
Integer empId;
Integer age;
public static void main(String[] args) {
Employee empOne = new Employee();
empOne.empName = "Raj";
empOne.empId = 1;
empOne.age = 45;
ComparableTest cmpOne = new ComparableTest();
cmpOne.name = "Raj";
cmpOne.age = 45;
if(empOne.compareTo(cmpOne) == 1) { //This line will throw coompile time error as now type checking perform for method
System.out.println("Equal Object");
} else {
System.out.println("Unequal Object");
}
}
@Override
public int compareTo(Employee o) {
if(this.age.equals(o.age)) {
return 1;
}
return 0;
}
}
Comparator Interface :
If a class is implementing a comparator interface, it can compare two objects of any type and this might throw an error at run time or we need to do
instance type check on object before doing comparison.
Instead of doing instance type check and perform comparison, we can use generics which provides type safety to code and performs compile time checking
and prevents runtime errors.
Example 1 :
import java.util.Comparator;
public class ComparatorTest implements Comparator {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof String && o2 instanceof String /*If instanceof check won't perform, any type object can be passed which will throw error at runtime*/
&& ((String)o1).length() == ((String)o2).length()) {
return 1;
}
return 0;
}
}
Exampe 1 using generics:
//Now this class can compare only String type object.
import java.util.Comparator;
public class ComparatorTest implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
if(o1.length() == o2.length()) {
return 1;
}
return 0;
}
}
Example 2 using generics :
import java.util.Comparator;
public class ComparatorTest implements Comparator<T> {
@Override
public int compare(T o1, T o2) {
if(o1.equals(o2)) {
return 1;
}
return 0;
}
}
In example 2, user can define type of comparator at time of creation of comparator object and comparison is performed based on equals method of type class as shown in example.

Note : Please provide feedbacks and suggestions.

2 comments:

  1. Good article. I have only had to use the comparable and comparator classes a handful of times, but you have provided interesting possibilities the next time I need to use one or the other. Thanks for posting this.

    ReplyDelete
  2. @jwhite1202: Thanks for your feedback.

    ReplyDelete