Wednesday, 26 August 2015

How to sort an arraylist of custom objects in Java

In the post How to sort ArrayList in Java you have already seen how to sort an ArrayList of Strings, Integers or Dates. In this post we'll see how to sort an ArrayList of custom objects.

In that post how to sort arrayList of strings we have already seen how to use Collections.sort method to sort such an ArrayList. The point to note here is that "All elements in the list must implement the Comparable interface" in order to use it with sort() method. So, if we have any custom class objects which we are storing in an ArrayList then that custom class should also implement Comparable interface so that the ArrayList can be used with sort method. Not doing so will result in compile time error.

Sorting arraylist containing custom object with Comparable

Let's say you have an Employee class. Objects of this Employee class are stored in an ArrayList and you want to sort it on first name and last name.

public class Employee implements Comparable<Employee> {
    private String lastName;
    private String firstName;
    private String empId;
    private int age;
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getEmpId() {
        return empId;
    }
    public void setEmpId(String empId) {
        this.empId = empId;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
    @Override
    public String toString() {
        
        return getFirstName() + " " + getLastName() + " " + getAge() + " " + getEmpId();
    }
    @Override
    public int compareTo(Employee o) {
        int firstCmp = this.getFirstName().compareTo(o.getFirstName());
        return firstCmp != 0 ? firstCmp :  this.getLastName().compareTo(o.getLastName());
    }
}
Class where sorting of the list will be done.
public class SortObjectList {
    public static void main(String[] args) {
        List<Employee> empList = new ArrayList<Employee>();
        // Storing elements in the arraylist
        empList.add(getData("E001", "Mishra", "Pyaremohan", 35));
        empList.add(getData("E002", "Smith", "John", 45));
        empList.add(getData("E003", "Sharma", "Ram", 23));
        empList.add(getData("E004", "Mishra", "Pyaremohan", 60));
        empList.add(getData("E005", "Caroll", "Eva", 32));
        empList.add(getData("E003", "Tiwari", "Ram", 23));
        
        System.out.println("Original List");
        for(Employee emp : empList){
            System.out.println("" + emp);
        }
        // Sorting the list
        Collections.sort(empList);
        
        System.out.println("Sorted List");
        for(Employee emp : empList){
            System.out.println("" + emp);
        }    
    }
                
    // Stub method 
    private static Employee getData(String empId, String lastName, String firstName, int age){
        Employee employee = new Employee();
        employee.setEmpId(empId);
        employee.setLastName(lastName);
        employee.setFirstName(firstName);
        employee.setAge(age);
        return employee;
    }    
}

Output

Original List
Pyaremohan Mishra 35 E001
John Smith 45 E002
Ram Sharma 23 E003
Pyaremohan Mishra 60 E004
Eva Caroll 32 E005
Ram Tiwari 23 E003
Sorted List
Eva Caroll 32 E005
John Smith 45 E002
Pyaremohan Mishra 35 E001
Pyaremohan Mishra 60 E004
Ram Sharma 23 E003
Ram Tiwari 23 E003

Sorting ArrayList containing custom objects using Comparator

Here in Employee class it implements the compareTo() method, where first names take precedence over last names. So this is the natural ordering for sorting the Employee class objects.

Now in case we want to sort in an order where, if names are same, they are sorted on the basis of age in descending order we can't use the already implemented compareTo() method of the Employee class. Other scenario is what if you want to sort some objects that don't implement Comparable?

To do either of these things, you'll need to provide a Comparator. An object of Comparator class is passed as a parameter in sort() method, this Comparator class object encapsulates an ordering.

  • Refer Difference between Comparable and Comparator to see the differences between the two interfaces Comparable and Comparator.
  • Comparator interface consists of a single method compare().

    public interface Comparator<T> {
        int compare(T o1, T o2);
    }
    

    The compare method compares its two arguments, returning a negative integer, 0, or a positive integer depending on whether the first argument is less than, equal to, or greater than the second. If either of the arguments has an inappropriate type for the Comparator, the compare method throws a ClassCastException.

    So the case where sorting logic is - if names are same, they are sorted on the basis of age in descending order you have to write a comparator class which will implement Comparator interface and provide implementation for the compare method.

    public class SortObjectList {
        public static void main(String[] args) {
            List<Employee> empList = new ArrayList<Employee>();
            // Storing elements in the arraylist
            empList.add(getData("E001", "Mishra", "Pyaremohan", 35));
            empList.add(getData("E002", "Smith", "John", 45));
            empList.add(getData("E003", "Sharma", "Ram", 23));
            empList.add(getData("E004", "Mishra", "Pyaremohan", 60));
            empList.add(getData("E005", "Caroll", "Eva", 32));
            empList.add(getData("E003", "Tiwari", "Ram", 23));
            
            System.out.println("Original List");
            for(Employee emp : empList){
                System.out.println("" + emp);
            }
            // Sorting the list
            Collections.sort(empList, new MyComparator());
                    
            System.out.println("Sorted List");
            for(Employee emp : empList){
                System.out.println("" + emp);
            }    
        }
                    
        // Stub method 
        private static Employee getData(String empId, String lastName, String firstName, int age){
            Employee employee = new Employee();
            employee.setEmpId(empId);
            employee.setLastName(lastName);
            employee.setFirstName(firstName);
            employee.setAge(age);
            return employee;
        }
        
        
    }
    
    class MyComparator implements Comparator<Employee>{
        @Override
        public int compare(Employee o1, Employee o2) {
            int firstCmp = o1.getFirstName().compareTo(o2.getFirstName());
            if(firstCmp == 0){
                int lastCmp = o1.getLastName().compareTo(o2.getLastName());
                if(lastCmp == 0){
                    return (o2.getAge() < o1.getAge() ? -1 :
                           (o2.getAge() == o1.getAge() ? 0 : 1));
                }else{
                    return lastCmp;
                }
                
            }else{
                return firstCmp;
            }        
        }    
    }
    

    Output

    Original List
    Pyaremohan Mishra 35 E001
    John Smith 45 E002
    Ram Sharma 23 E003
    Pyaremohan Mishra 60 E004
    Eva Caroll 32 E005
    Ram Tiwari 23 E003
    Sorted List
    Eva Caroll 32 E005
    John Smith 45 E002
    Pyaremohan Mishra 60 E004
    Pyaremohan Mishra 35 E001
    Ram Sharma 23 E003
    Ram Tiwari 23 E003
    

    Here it can be seen that the name which is same is sorted by age in descending order. The logic for sorting is in the compare method.

    That's all for this topic how to sort an ArrayList of custom objects in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


    Related Topics

    1. How ArrayList works internally in Java
    2. Difference between Comparable and Comparator
    3. How to join lists in Java
    4. How to sort an ArrayList in descending order
    5. How to remove duplicate elements from an ArrayList in Java
    6. Java Collections interview questions

    You may also like -

    1 comment:

    1. Comparator is a good way to sort an ArrayList of custom objects. That way you can provide more than one comparator meaning more than one way to sort the list.

      ReplyDelete