Sort ArrayList of Objects using Comparable and Comparator interface
In the previous post, we have seen how to sort arraylist in descending order. In that post , we have sorted out the arraylist for String and Integer values. We have used Collections.sort() method to sort the list. What if, we have Objects in the arrayList instead of String and Integer values. Can we use Collections.sort() method to sort the list. Let’s understand with the example.
Why do we need Comparable and Comparator interface?
Let’s consider that we have class called Address which has properties like StreetName, City, Country etc.
package com.testingpool.demo2; public class Address { private int streetNo; private String city; private String country; public Address(int streetNo, String City, String Country){ this.streetNo = streetNo; this.city = City; this.country = Country; } public int getStreetNo(){ return streetNo; } public void setStreetNo(int StreetNo){ this.streetNo = StreetNo; } public String getCity(){ return city; } public void setCity(String City){ this.city = City; } public String getCountry(){ return country; } public void setCountry(String country){ this.country = country; } }
Now, Let’s create an arrayList of Address Objects. It will give a compile time error and you can execute it to see the error in console.
package com.testingpool.demo2; import java.util.ArrayList; import java.util.Collections; public class SortArrayListEx { public static void main(String[] args) { ArrayList<Address> addList = new ArrayList<Address>(); addList.add(new Address(86,"Bangalore","India")); addList.add(new Address(100,"Pune","India")); addList.add(new Address(33,"New York","US")); Collections.sort(addList); for(Address add : addList){ System.out.println(add); } } }
Output:
So we get this error that type address is not a valid substitute. That means just simply sort method does not work for arraylist of objects. This can be sorted out by using interfaces comparable and comparator.
Let’s see how to use them.
Sorting ArrayList of Object with the help of Comparable Interface:
Suppose, we need to sort the arrayList on the basis of StreetNo. For that, we will implements the comparable interface and then override the CompareTo method.
package com.testingpool.demo2; public class Address implements Comparable{ private int streetNo; private String city; private String country; public Address(int streetNo, String City, String Country){ this.streetNo = streetNo; this.city = City; this.country = Country; } public int getStreetNo(){ return streetNo; } public void setStreetNo(int StreetNo){ this.streetNo = StreetNo; } public String getCity(){ return city; } public void setCity(String City){ this.city = City; } public String getCountry(){ return country; } public void setCountry(String country){ this.country = country; } @Override public int compareTo(Object compareStreetNo) { //Make sure object is of type Address by casting it //For ascending order int CompareStreet = ((Address) compareStreetNo).getStreetNo(); return this.streetNo - CompareStreet; //for descending order //return CompareStreet - this.streetNo; } @Override public String toString() { return "[ StreetNo =" + streetNo + ", City =" + city + ", Country =" + country + "]"; } }
Now, We can call the same program to sort the arraylist.
package com.testingpool.demo2; import java.util.ArrayList; import java.util.Collections; public class SortArrayListEx { public static void main(String[] args) { ArrayList<Address> addList = new ArrayList<Address>(); addList.add(new Address(86,"Bangalore","India")); addList.add(new Address(100,"Pune","India")); addList.add(new Address(33,"New York","US")); Collections.sort(addList); for(Address add : addList){ System.out.println(add); } } }
Output:
Why do we need comparator when Comparable interface is doing the required job for us?
By using Comparable, we can only sort single property and that should be of integer type. For sorting multiple properties, we need to use comparator.
Sorting ArrayList of Object with the help of Comparator Interface:
Let’s implements the Comparator interface and perform sorting on the basis of StreetNo and City.
package com.testingpool.demo2; import java.util.Comparator; public class Address implements Comparator{ private int streetNo; private String city; private String country; public Address(int streetNo, String City, String Country){ this.streetNo = streetNo; this.city = City; this.country = Country; } public int getStreetNo(){ return streetNo; } public void setStreetNo(int StreetNo){ this.streetNo = StreetNo; } public String getCity(){ return city; } public void setCity(String City){ this.city = City; } public String getCountry(){ return country; } public void setCountry(String country){ this.country = country; } //Comparator for sorting the arraylist by StreetNo public static Comparator<Address> streetNoComparator = new Comparator<Address>(){ @Override public int compare(Address A1, Address A2) { int streetNum1 = A1.getStreetNo(); int streetNum2 = A2.getStreetNo(); //ascending order return streetNum1 - streetNum2; //descending order //return streetNum2 - streetNum1; } }; //Comparator for sorting the arraylist by city public static Comparator<Address> CityComparator = new Comparator<Address>(){ @Override public int compare(Address A1, Address A2) { String city1 = A1.getCity().toUpperCase(); String city2 = A2.getCity().toUpperCase(); //ascending order return city1.compareTo(city2); //descending order //return city2.compareTo(city1); } }; @Override public String toString() { return "[ StreetNo =" + streetNo + ", City =" + city + ", Country =" + country + "]"; } @Override public int compare(Object o1, Object o2) { // TODO Auto-generated method stub return 0; } }
Output:
[ StreetNo =33, City =New York, Country =US] [ StreetNo =86, City =Bangalore, Country =India] [ StreetNo =100, City =Pune, Country =India]
[ StreetNo =86, City =Bangalore, Country =India] [ StreetNo =33, City =New York, Country =US] [ StreetNo =100, City =Pune, Country =India]