Sorting objects is commonly used especially in the presentation layer of an enterprise application. Developers unfamiliar with the Collections Framework API would write their own sorting algorithm unaware of the availability of Comparable and Comparator interfaces to satisfy their needs.
The Comparable interface is used if you need to implement a default sorting behavior of the object you need sorted. Let’s have the following class as an example :
public class Player{
private final String lastName;
private final String firstName;
private final Float pointAverage;
public Player(String lastName, String firstName, Float pointAverage) {
this.lastName = lastName;
this.firstName = firstName;
this.pointAverage = pointAverage;
}
public String getLastName() {
return lastName;
}
public String getFirstName() {
return firstName;
}
public Float getPointAverage() {
return pointAverage;
}
@Override
public String toString() {
return lastName + ", " + firstName + " " + pointAverage;
}
}
Let’s create a List of Player objects :
List<Player> playerList = new ArrayList<Player>();
playerList.add(new Player("Jordan", "Michael", 32.4f));
playerList.add(new Player("James", "Lebron", 28.3f));
playerList.add(new Player("Bryant", "Kobe", 29.2f));
playerList.add(new Player("Paul", "Chris", 26.2f));
To be able to sort playerList by last name, we can modify Player class to implement the compareTo() method of the Comparable interface :
public class Player implements Comparable<Player> {
private final String lastName;
private final String firstName;
private final Float pointAverage;
public Player(String lastName, String firstName, Float pointAverage) {
this.lastName = lastName;
this.firstName = firstName;
this.pointAverage = pointAverage;
}
public String getLastName() {
return lastName;
}
public String getFirstName() {
return firstName;
}
public Float getPointAverage() {
return pointAverage;
}
@Override
public String toString() {
return lastName + ", " + firstName + " " + pointAverage;
}
public int compareTo(Player player) {
return this.getLastName().compareTo(player.getLastName());
}
}
We can now do the following :
Collections.sort(playerList);
for (IPerson person : playerList){
System.out.println(person);
}
An the output is
Bryant, Kobe 29.2
James, Lebron 28.3
Jordan, Michael 32.4
Paul, Chris 26.2
As you can see, using the Comparable interface can only be used as a default sorting technique. Most of the time, you may need to sort a certain List of records by their field values. This where the Comparator interface comes very useful where you have to implement the compare() method:
import java.util.Comparator;
public class PlayerComparator implements Comparator<Player> {
public enum SortType {
ASCENDING, DESCENDING
}
public enum SortField {
LAST_NAME,
FIRST_NAME,
POINT_AVERAGE
}
private final SortType sortType;
private final SortField sortField;
public PlayerComparator(SortType sortType, SortField sortField) {
this.sortType = sortType;
this.sortField = sortField;
}
public int compare(Player person1, Player person2) {
int compare = 0;
switch (sortType){
case ASCENDING:
compare = handleSortField(person1, person2, compare);
break;
case DESCENDING:
compare = handleSortField(person2, person1, compare);
}
return compare;
}
private int handleSortField(Player person1, Player person2, int compare) {
switch (sortField){
case LAST_NAME :
compare = person1.getLastName().compareTo(person2.getLastName());
break;
case FIRST_NAME :
compare = person1.getFirstName().compareTo(person2.getFirstName());
break;
case POINT_AVERAGE:
compare = person1.getPointAverage().compareTo(person2.getPointAverage());
}
return compare;
}
}
Now, should have more flexibility in our code to sort the list:
Collections.sort(playerList, new PlayerComparator(PlayerComparator.SortType.DESCENDING,
PlayerComparator.SortField.POINT_AVERAGE));
for (IPerson person : playerList){
System.out.println(person);
}
And now, we get the following output:
Jordan, Michael 32.4
Bryant, Kobe 29.2
James, Lebron 28.3
Paul, Chris 26.2
As you can see, understanding how Comparable and Comparator interfaces can sort your List can save you a lot of coding your own sort algorithms.