In this tutorial we will see how to use two interfaces Comparable and Comparator for sorting collection data. When to use which interface and what if both the interfaces are used in same application.
So lets start with Comparable. This interface has declaration for only one method compareTo(T a) where T is a type object. For better clarity we will create a bean class ComparableEmployeeBean that has few instance variables to store employee information like id, first name, last name, date of birth. Since this class is implementing interface Comparable we need to provide implementation for compareTo method. This method provides a logic to sort ComparableEmployeeBean(s) in a Sorted collection e.g. SortedSet, TreeSet etc. So following is our bean class with implementation that will sort employees based on their employee id.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.techcielo.corejava.bean; | |
public class ComparableEmployeeBean implements Comparable<ComparableEmployeeBean> { | |
public ComparableEmployeeBean(String empId,String fName,String lName) { | |
this.empId=empId; | |
this.empFirstName=fName; | |
this.empLastName=lName; | |
} | |
private String empId; | |
private String empFirstName; | |
private String empLastName; | |
public String getEmpId() { | |
return empId; | |
} | |
public void setEmpId(String empId) { | |
this.empId = empId; | |
} | |
public String getEmpFirstName() { | |
return empFirstName; | |
} | |
public void setEmpFirstName(String empFirstName) { | |
this.empFirstName = empFirstName; | |
} | |
public String getEmpLastName() { | |
return empLastName; | |
} | |
public void setEmpLastName(String empLastName) { | |
this.empLastName = empLastName; | |
} | |
@Override | |
public String toString() { | |
return empId+":"+empFirstName+":"+empLastName; | |
} | |
@Override | |
public int compareTo(ComparableEmployeeBean o) { | |
return this.empId.compareTo(o.empId); | |
} | |
} |
From this code we can understand following about Comparable
So now we will insert few employees in this bean class and display them. Following code will insert three employees and add them in a sorted set.
This code will print following output.
[1:Foo:Bar, 2:Foo:Baz, 3:Boo:Baz]
There is a word of caution here. If your implementation returns 0 for comparison between bean to be added and any bean in collection, these two beans will be treated as equal and new bean will not be added in Collection. So in our example if we try to add another employee with different first name and last name but same employee id, Set will assume that this record is already present and will ignore new entry. Interested user can trying adding employee with id 2, name Bar and last name Baz. So remember implementation of Comparable (or even Comparator) should be in line with implementation of equals method of our bean/VO class.
So now lets see what is another interface Comparator. Comparator interface too will have method compare with two arguments. So class that implements this interface will provide logic external to bean/VO to be compared/sorted. So lets create a class that will use Comparator interface to sort employees based on first name and last name.
This implementation will override the default behavior implemented by Comparable. So if we initialize SortedSet with this Comparator, it will sort employees based on their first name and last name. So following is the code.
This code will result in following output.
[3:Boo:Baz, 1:Foo:Bar, 2:Foo:Baz]
- When we want to have default sorting for some bean class we will implement Comparable.
- When code bean/VO to be sorted is available to us we can implement Comparable.
So now we will insert few employees in this bean class and display them. Following code will insert three employees and add them in a sorted set.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.techcielo.corejava.main; | |
import java.util.*; | |
import com.techcielo.corejava.bean.ComparableEmployeeBean; | |
public class SortingMain { | |
public static void main(String[] args) { | |
SortedSet<ComparableEmployeeBean> empSet = new TreeSet<ComparableEmployeeBean>(); | |
empSet.add(new ComparableEmployeeBean("1", "Foo", "Bar")); | |
empSet.add(new ComparableEmployeeBean("3", "Boo", "Baz")); | |
empSet.add(new ComparableEmployeeBean("2", "Foo", "Baz")); | |
System.out.println(empSet); | |
} | |
} |
[1:Foo:Bar, 2:Foo:Baz, 3:Boo:Baz]
There is a word of caution here. If your implementation returns 0 for comparison between bean to be added and any bean in collection, these two beans will be treated as equal and new bean will not be added in Collection. So in our example if we try to add another employee with different first name and last name but same employee id, Set will assume that this record is already present and will ignore new entry. Interested user can trying adding employee with id 2, name Bar and last name Baz. So remember implementation of Comparable (or even Comparator) should be in line with implementation of equals method of our bean/VO class.
So now lets see what is another interface Comparator. Comparator interface too will have method compare with two arguments. So class that implements this interface will provide logic external to bean/VO to be compared/sorted. So lets create a class that will use Comparator interface to sort employees based on first name and last name.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.techcielo.corejava.util; | |
import java.util.Comparator; | |
import com.techcielo.corejava.bean.ComparableEmployeeBean; | |
public class EmployeeNameComparator implements Comparator<ComparableEmployeeBean>{ | |
@Override | |
public int compare(ComparableEmployeeBean emp1, ComparableEmployeeBean emp2) { | |
if(emp1.getEmpFirstName().equals(emp2.getEmpFirstName())){ | |
return emp1.getEmpLastName().compareTo(emp2.getEmpLastName()); | |
} | |
else{ | |
return emp1.getEmpFirstName().compareTo(emp2.getEmpFirstName()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.techcielo.corejava.main; | |
import java.util.*; | |
import com.techcielo.corejava.bean.ComparableEmployeeBean; | |
import com.techcielo.corejava.util.EmployeeNameComparator; | |
public class ComparatorMain { | |
public static void main(String[] args) { | |
SortedSet<ComparableEmployeeBean> empSet = new TreeSet<ComparableEmployeeBean>( | |
new EmployeeNameComparator()); | |
empSet.add(new ComparableEmployeeBean("1", "Foo", "Bar")); | |
empSet.add(new ComparableEmployeeBean("3", "Boo", "Baz")); | |
empSet.add(new ComparableEmployeeBean("2", "Foo", "Baz")); | |
System.out.println(empSet); | |
} | |
} |
This code will result in following output.
[3:Boo:Baz, 1:Foo:Bar, 2:Foo:Baz]
We can say following about Comparator.
- It provides sorting logic out side the bean.
- It will over ride default behavior of bean achieved by implementing Comparable.
- When there is no access to code for bean class Comparator will be default option for sorting.