In the previous post about the Comparable interface I explained how you can extend a class of objects that implement the Comparable interface and then order them in a list according to the logic defined in the overridden method compareTo.
If you want to be able to sort the list according to a number of different criteria you must use the Comparator interface, for example, in the case of a list of countries, it is possible that you want to order them not only alphabetically but also in order of area or population.
A very important difference between Comparable and Comparator is as follows:
- using Comparable, you must modify the object class you want to sort implementing Comparable
- using Comparator, you must create a new class that implements Comparator; this new class can be a public class in its own file. java, or can also be an inner class because it is intimately tied to the outer class of objects to be sorted
The only method required by the Comparator interface is compare which has as argument 2 objects of the same type you are sorting and the return value is an integer.
So the call to the method is:
int result = compare(x, y)
where x and y are objects of the same type of those in the list and result is an integer that takes the value:
<0 if x<y
==0 if x==y
>0 if x>y
After you have created the class Comparator you can use the static method Collections.sort(List list, Comparator c) to sort the list.
Look at the following example:
- Main.java
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Main { public static void main(String[] args) { List<Country> myCountryList = new ArrayList<Country>(); Country germany = new Country("Germany", 357021, 81305856); Country french = new Country("French", 547030, 65630692); Country unitedKingdom = new Country("United Kingdom", 244820, 63047162); Country italy = new Country("Italy", 301230, 61261254); Country spain = new Country("Spain", 504851, 47042984); myCountryList.add(germany); myCountryList.add(french); myCountryList.add(unitedKingdom); myCountryList.add(italy); myCountryList.add(spain); // FIRST SECTION System.out.println("\nSORTED LIST BY NAME:"); Collections.sort(myCountryList); for (Country item : myCountryList) { System.out.println(item.getName()); } // SECOND SECTION System.out.println("\nSORTED LIST BY AREA:"); Collections.sort(myCountryList, new Country.AreaComparator()); for (Country item : myCountryList) { System.out.println(item.getName()); } // THIRD SECTION System.out.println("\nSORTED LIST BY POPULATION IN DESCENDING ORDER:"); Collections.sort(myCountryList, Collections.reverseOrder(new Country.PopulationComparator())); for (Country item : myCountryList) { System.out.println(item.getName()); } // FOURTH SECTION System.out.println("\nSORTED LIST BY NAME IN DESCENDING ORDER:"); Collections.sort(myCountryList, Collections.reverseOrder()); for (Country item : myCountryList) { System.out.println(item.getName()); } } }
- Country.java
import java.util.Comparator; public class Country implements Comparable<Country> { static class AreaComparator implements Comparator<Country> { @Override public int compare(Country o1, Country o2) { int result; result = o1.getArea() - o2.getArea(); return result; } } static class PopulationComparator implements Comparator<Country> { @Override public int compare(Country o1, Country o2) { int result; result = o1.getPopulation() - o2.getPopulation(); return result; } } private int area; private String name; private int population; public Country(String name, int area, int population) { this.name = name; this.area = area; this.population = population; } @Override public int compareTo(Country o) { int result; result = name.compareTo(o.getName()); return result; } public int getArea() { return area; } public String getName() { return name; } public int getPopulation() { return population; } public void setArea(int area) { this.area = area; } public void setName(String name) { this.name = name; } public void setPopulation(int population) { this.population = population; } }
The output is:
SORTED LIST BY NAME: French Germany Italy Spain United Kingdom SORTED LIST BY AREA: United Kingdom Italy Germany Spain French SORTED LIST BY POPULATION IN DESCENDING ORDER: Germany French United Kingdom Italy Spain SORTED LIST BY NAME IN DESCENDING ORDER: United Kingdom Spain Italy Germany French
The class Country implements Comparable, this is not necessary to use Comparator but it is only useful to be able to make a comparison.
In the class Country there are 2 static inner classes (static to be used without an instance of the class Country) that override the compare method.
There are 4 sections in Main.java: in the first section the sort is by name without using Comparator but only the Comparable interface, in the second section the sort is by area; in the third section of the sort is descending by population (reverseOrder (Comparator cmp) returns a comparator that imposes the reverse ordering of the specified comparator); in the fourth section the sort is descending by name (reverseOrder () returns a comparator that imposes the reverse order of that defined in the Comparable interface).
Similarly, you can also sort the arrays using the Arrays.sort(Object[] a, Comparator c) method.
Leave a Reply