Wednesday, 26 August 2015

How to sort an arraylist of custom objects in Java

In ArrayList elements are added in sequential order and while displaying the elements by iterating an arraylist that same default ordering will be used. Sometimes we do have a requirement to sort an arraylist in ascending or descending order. In this post we'll see how to sort an ArrayList of custom objects.

In the 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 array list then that custom class should also implement Comparable interface so that that array list 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 we have an Employee class. Objects of this Employee class are stored in an array list and we 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 object 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 that encapsulates an ordering. Comparator interface consists of a single method.

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 -

No comments:

Post a Comment