Monday, 8 February 2016

How to sort an ArrayList in descending order

When you add elements to an ArrayList, elements are added in sequential order and while iterating an arraylist same sequential order will be used to retrieve the elements.

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 in descending order.

Sorting ArrayList in descending order

For sorting ArrayList in descending order there are two options

  1. Use method reverseOrder() provided by Collections class.
  2. General form and description

    public static <T> Comparator<T> reverseOrder()
    
    Returns a comparator that imposes the reverse of the natural ordering on a collection of objects that implement the Comparable interface.
  3. Using a custom comparator.

If you are using the first option then you must also know about the overloaded method sort provided by the Collections class.

  • public static <T> void sort(List<T> list, Comparator<? super T> c) - Sorts the specified list according to the order induced by the specified comparator. All elements in the list must be mutually comparable using the specified comparator (that is, c.compare(e1, e2)must not throw a ClassCastException for any elements e1 and e2 in the list).

reverseOrder() method mentioned above can be provided as the second parameter in the sort method mentioned above and you will get the ArrayList in reverse order. Let's see an example -

Sorting Using reverseOrder method

public class SortListDemo {

    public static void main(String[] args) {
        // Using diamond operator (Right side no type specified)
        // Available from Java7 onwards
        List<String> cityList = new ArrayList<>();
        cityList.add("Delhi");
        cityList.add("Mumbai");
        cityList.add("Bangalore");
        cityList.add("Chennai");
        cityList.add("Kolkata");
        cityList.add("Mumbai");
        // sorting the list in descending order
        Collections.sort(cityList, Collections.reverseOrder());
        //Displaying the list
        for(String city : cityList){
            System.out.println("Name " + city);
        }
    }
}

Output

Name Mumbai
Name Mumbai
Name Kolkata
Name Delhi
Name Chennai
Name Bangalore

Sorting Using custom Comparator

Internally reverseOrder method calls a Comparator class to do the sorting in reverse order. You can do it yourself too by writing your own comparator class.

public class SortListDemo {
    public static void main(String[] args) {
        // Using diamond operator (Right side no type specified)
        // Available from Java7 onwards
        List<String> cityList = new ArrayList<>();
        cityList.add("Delhi");
        cityList.add("Mumbai");
        cityList.add("Bangalore");
        cityList.add("Chennai");
        cityList.add("Kolkata");
        cityList.add("Mumbai");
        // sorting the list in descending order
        Collections.sort(cityList, new MyComparator());
        //Displaying the list
        for(String city : cityList){
            System.out.println("Name " + city);
        }
    }
}


//Custom comparator class
class MyComparator implements Comparator<String>{
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }    
}

Comparator with Java 8

Since Comparator is a functional interface so we can use lambda expression to provide implementation of its abstract method. That will reduce the custom comparator implementation to a single line. Don't forget to import the comparator interface though.

Example code

public class SortListDemo {
    public static void main(String[] args) {
        // Using diamond operator (Right side no type specified)
        // Available from Java7 onwards
        List<String> cityList = new ArrayList<>();
        cityList.add("Delhi");
        cityList.add("Mumbai");
        cityList.add("Bangalore");
        cityList.add("Chennai");
        cityList.add("Kolkata");
        cityList.add("Mumbai");
        // sorting the list in descending order
        Collections.sort(cityList, (String a, String b)->  b.compareTo(a));
        //Displaying the list
        for(String city : cityList){
            System.out.println("Name " + city);
        }
    }
}

Output

Name Mumbai
Name Mumbai
Name Kolkata
Name Delhi
Name Chennai
Name Bangalore

Sorting ArrayList of custom objects

Let's say there is an Employee class with fields EmpId, FirstName, LastName and Age and you want to sort elements as per following rules.

  • Sort on FirstName in ascending order.
  • If FirstName is same then sort on LastName in ascending order.
  • If both FirstName and LastName are same the sort on Age in Descending order.

Employee Class

public class 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();
    }
}

Sorting logic

public class SortObjList {

    public static void main(String[] args) {
        List<Employee> empList = new ArrayList<Employee>();
        // Storing elements in the arraylist
        empList.add(getData("E001", "Mishra", "Ram", 30));
        empList.add(getData("E002", "Smith", "John", 45));
        empList.add(getData("E003", "Smith", "John", 23));
        empList.add(getData("E004", "Mishra", "Pyaremohan", 60));
        empList.add(getData("E005", "Caroll", "Eva", 32));
        empList.add(getData("E003", "Tiwari", "Ram", 35));
            
        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
Ram Mishra 30 E001
John Smith 45 E002
John Smith 23 E003
Pyaremohan Mishra 60 E004
Eva Caroll 32 E005
Ram Tiwari 35 E003

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

Here it can be seen that Employees are sorted on the basis of first name in ascending order. There are two John Smiths so in that case sorting is done on the basis of age in descending order. And For Ram Tiwari and Ram Mishra since first name is same so sorting is done on the basis of last name in ascending order.

That's all for this topic How to sort ArrayList in descending order. 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. How to sort arraylist of custom objects in Java
  3. How to remove duplicate elements from an ArrayList in Java
  4. How Linked List class works internally in Java
  5. CopyOnWriteArrayList in Java - The thread safe variant of ArrayList
  6. Java Collections interview questions

You may also like -

No comments:

Post a Comment