Java Comparator Interface
The Comparator interface gives us the liberty to simultaneously use more than one common attributes to sort objects created from a class. This is why it is different from Comparable interface. It belongs to the java.util package. To use the Comparator interface, a separate class is defined which implements the Comparator and its compare() method is overridden. It is inside this method that we write the logic code of sorting our SmartPhone objects.
From the definition of our SmartPhone class, three attributes were declared, which are name, yearOfManufacture and batteryCapacity. To use each of these attributes in conjunction with the Comparator interface to sort our SmartPhone objects, three separate classes (NameComparator, YearOfManufactureComparator and BatteryCapacityComparator) will be defined, and each of these classes shall implement the Comparator interface. Then, the compare() method shall be overridden. This is shown below:
// NameComparator class
import java.util.Comparator;
public class NameComparator implements Comparator<SmartPhone> {
@Override
public int compare(SmartPhone sp1, SmartPhone sp2) {
}
}
// YearOfManufactureComparator class
import java.util.Comparator;
public class YearOfManufactureComparator implements Comparator<SmartPhone> {
@Override
public int compare(SmartPhone sp1, SmartPhone sp2) {
}
}
// BatteryCapacityComparator class
import java.util.Comparator;
public class BatteryCapacityComparator implements Comparator<SmartPhone> {
@Override
public int compare(SmartPhone sp1, SmartPhone sp2) {
}
}
The compare method takes in two SmartPhone objects as parameters and returns an integer value when the two objects are compared. Zero is returned if the chosen attribute of the two objects is equal. A negative value is returned if the attribute of the second object(sp2) is greater than the first object (sp1) attribute. A positive value is returned if sp1 attribute is greater than sp2 attribute. Inside the compare() method of the NameComparator class, we use the name attributes, by calling getName() method of the two SmartPhone objects to perform the comparision like so:
public class NameComparator implements Comparator<SmartPhone> {
@Override
public int compare(SmartPhone sp1, SmartPhone sp2) {
return sp1.getName().compareTo(sp2.getName());
}
}
Here, zero will be returned if the name of the two SmartPhone objects are the same. A negative value is returned if sp1 is less than sp2, and a positive value is returned if sp1 is greater than sp2.
For the YearOfManufactureComparator class, we use the yearOfManufacture attribute of the two objects to perform the comparison like so:
public class YearOfManufactureComparator implements Comparator<SmartPhone> {
@Override
public int compare(SmartPhone sp1, SmartPhone sp2) {
returnsp1.getYearOfManufacture().compareTo(sp2.getYearOfManufacture());
}
}
Here also, if the yearOfManufacture of both objects are the same, zero is returned. If the yearOfManufacture of sp1 is lesser than that of sp2, a negative value is returned, and if that of sp1 is greater than that of sp2, a positive value is returned.
Lastly, for the BatteryCapacityComparator class, we use the batteryCapacity attribute of the two objects to perform the comparison like so:
public class BatteryCapacityComparator implements Comparator<SmartPhone> {
@Override
public int compare(SmartPhone sp1, SmartPhone sp2) {
return sp1.getBatteryCapacity() - sp2.getBatteryCapacity();
}
}
Recall that batteryCapacity attribute is an int variable, thus we only need to use the minus sign to compare the batteryCapacity of both objects. As usual, zero is returned if both objects have the same batteryCapacity value. A negative value is retuned if sp1 batteryCapacity is lesser than that of sp2 batteryCapacity. A positive value is returned if sp1 batteryCapacity is greater than that of sp2 batteryCapacity.
Below is a java program to demonstrate sorting using the Comparator interface.
import java.util.ArrayList;
import java.util.Collections;
public class SmartphoneMain {
public static void main(String[] args) {
ArrayList<SmartPhone> spList =
new ArrayList<>();
spList.add(
new SmartPhone("Motorola", "2008", 2340));
spList.add(
new SmartPhone("Redmi", "2017", 4000));
spList.add(
new SmartPhone("Infinix", "2010", 3000));
spList.add(
new SmartPhone("Samsung", "2016", 3500));
spList.add(
new SmartPhone("Oppo", "2018", 4000));
spList.add(
new SmartPhone("Huawei", "2019", 5000));
// UNSORTED
System.out.println("UNSORTED SMART PHONES");
for (SmartPhone sp: spList) {
System.out.println(sp);
}
System.out.println("SORTED SMART PHONE OBJECTS USING THE NAME
ATTRIBUTE");
// SORTED WITH NameComparator
Collections.sort(spList, new NameComparator());
for (SmartPhone sp: spList) {
System.out.println(sp);
}
System.out.println("SORTED SMART PHONE OBJECTS USING THE YEAR OF
MANUFACTURE ATTRIBUTE");
// SORTED WITH YearOfManufacturerComparator
Collections.sort(spList, new YearOfManufactureComparator());
for (SmartPhone sp: spList) {
System.out.println(sp);
}
System.out.println("SORTED SMART PHONE OBJECTS USING THE BATTERY
CAPACITY ATTRIBUTE");
// SORTED WITH BatteryCapacityComparator
Collections.sort(spList, new BatteryCapacityComparator());
for (SmartPhone sp: spList) {
System.out.println(sp);
}
}
}
Below is the outcome of the results:
UNSORTED SMART PHONES
SmartPhone{name='Motorola', yearOfManufacture='2008', batteryCapacity=2340}
SmartPhone{name='Redmi', yearOfManufacture='2017', batteryCapacity=4000}
SmartPhone{name='Infinix', yearOfManufacture='2010', batteryCapacity=3000}
SmartPhone{name='Samsung', yearOfManufacture='2016', batteryCapacity=3500}
SmartPhone{name='Oppo', yearOfManufacture='2018', batteryCapacity=4000}
SmartPhone{name='Huawei', yearOfManufacture='2019', batteryCapacity=5000}
SORTED SMART PHONE OBJECTS USING THE NAME ATTRIBUTE
SmartPhone{name='Huawei', yearOfManufacture='2019', batteryCapacity=5000}
SmartPhone{name='Infinix', yearOfManufacture='2010', batteryCapacity=3000}
SmartPhone{name='Motorola', yearOfManufacture='2008', batteryCapacity=2340}
SmartPhone{name='Oppo', yearOfManufacture='2018', batteryCapacity=4000}
SmartPhone{name='Redmi', yearOfManufacture='2017', batteryCapacity=4000}
SmartPhone{name='Samsung', yearOfManufacture='2016', batteryCapacity=3500}
SORTED SMART PHONE OBJECTS USING THE YEAR OF MANUFACTURE ATTRIBUTE
SmartPhone{name='Motorola', yearOfManufacture='2008', batteryCapacity=2340}
SmartPhone{name='Infinix', yearOfManufacture='2010', batteryCapacity=3000}
SmartPhone{name='Samsung', yearOfManufacture='2016', batteryCapacity=3500}
SmartPhone{name='Redmi', yearOfManufacture='2017', batteryCapacity=4000}
SmartPhone{name='Oppo', yearOfManufacture='2018', batteryCapacity=4000}
SmartPhone{name='Huawei', yearOfManufacture='2019', batteryCapacity=5000}
SORTED SMART PHONE OBJECTS USING THE BATTERY CAPACITY ATTRIBUTE
SmartPhone{name='Motorola', yearOfManufacture='2008', batteryCapacity=2340}
SmartPhone{name='Infinix', yearOfManufacture='2010', batteryCapacity=3000}
SmartPhone{name='Samsung', yearOfManufacture='2016', batteryCapacity=3500}
SmartPhone{name='Redmi', yearOfManufacture='2017', batteryCapacity=4000}
SmartPhone{name='Oppo', yearOfManufacture='2018', batteryCapacity=4000}
SmartPhone{name='Huawei', yearOfManufacture='2019', batteryCapacity=5000}
Looking at the results, you’ll see that the outcomes were ordered based on the object of the Comparator class passed into the Collections.sort() method.
I hope you now have a solid understanding of Java Sorting interfaces and how to use them confidently.
Thank you for reading this article. Peace to your soul!
