Sunday, September 12, 2021

How to Sort 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 Java.

In order to sort an ArrayList of objects you can use sort() method provided by the Collections class, which takes List as an argument. Note that there are two overloaded variants of the sort() method.

  • sort(List<T> list)- If you are using this method to sort ArrayList of objects, the class whose objects are stored in the List should implement Comparable interface. If the class whose objects are stored in the List doesn’t implement the Comparable interface and you pass that list as an argument in sort(List<T> list) method that will result in compile time error. See example.
  • sort(List<T> list, Comparator<? super T> c)- This is another overloaded sort() method where you can pass your own Comparator along with the List that has to be sorted. See example.

Let’s see examples using both Comparable and Comparator interfaces to sort ArrayList of objects in Java.

Sorting ArrayList containing custom objects using 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 both 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

Some of the points to note about this program are-

  1. Employee class whose objects are stored in the ArrayList implements the Comparable interface and provides implementation of the compareTo() method.
  2. compareTo() method implementation provides logic for elements ordering.
  3. Collections.sort() method is used to sort the List.

Sorting ArrayList containing custom objects using Comparator

In the above example Employee class implements the compareTo() method, where first name takes precedence over last name. So this is the natural ordering for sorting the Employee class objects.

Now in case you want to sort using the following order-

If names are same, they are sorted on the basis of age in descending order.

If you have to sort using this rule you 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 sort an ArrayList of objects in Java using any of the above mentioned scenarios, 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. You will also have to use that variant of the sort() method where you can pass Comparator.

    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 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 ArrayList And LinkedList in Java
    3. How to Remove Elements From an ArrayList in Java
    4. How and Why to Synchronize ArrayList in Java
    5. Java Collections Interview Questions And Answers

    You may also like-

    1. How HashMap Works Internally in Java
    2. Difference Between ArrayList And CopyOnWriteArrayList in Java
    3. Thread Priority in Java Multi-Threading
    4. final Vs finally Vs finalize in Java
    5. Executor And ExecutorService in Java With Examples
    6. Java DelayQueue With Examples
    7. Why main Method static in Java
    8. Java Reflection API Tutorial

    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