Sorting ArrayList in Java

The collection is a Java framework that provides interfaces (Set, List, Queue, and so on) and classes (ArrayList, LinkedList, and so on) for storing a collection of objects. These classes keep data in random order. Sorting is a term used to describe the process of arranging data in an orderly fashion. You can do sorting in two ways: ascending or descending order.

This section will explore how to sort an ArrayList in ascending and descending order.

ArrayList

ArrayList is a Collections framework class in Java, defined in the Java.util package. It is a descendant of the AbstractList class. Further, it keeps track of the elements in real-time. ArrayList has the advantage of having no size limit. It is more adaptable than a standard array. Also, it may contain duplicate items. Because it implements the List interface, we can utilize all of the List interface’s methods. An ArrayList can be sorted in two ways: ascending and descending. In Java, the Collections class has two methods for sorting an ArrayList.

  • sort()
  • reverseOrder()

Collections.sort() as a method for sorting data in a collection

The sort() function of the Collections class in Java is used to sort an ArrayList. It takes an ArrayList object as an argument and returns an ArrayList that has been sorted in ascending order according to the natural ordering of its elements.

The syntax is as follows:

public static <T extends Comparable<? super T>> void sort(List<T> list)  

Remember that all elements in the ArrayList must be comparable to each other. Else the ClassCastException will be thrown. Mutually similar means that the elements in the list must be of the same type. Take, for example, the following code snippet:

    //creating an instance of ArrayList that contains String type elements  
    ArrayList<String> list = new ArrayList<String>();   
    list.add("HP");  
    list.add(321);   
    list.add("IBM");  
    list.add("DELL");  

In the example above, a list comprises four members, three of which are of the String type and one of which is the Integer type. The String’s three elements are interchangeable, but the Integer’s element is not. As a result, the elements in the list must all be of the same type.

Collections.reverseOrder() as a method that reverses the order of items in a collection

You can use the reverseOrder() method of the Java Collections class to sort an ArrayList in descending order. It allows us to reverse-lexicographically sort the ArrayList. The Syntax of .reverseOrder() is as follows:

 public static <T> Comparator<T> reverseOrder()  

It returns a comparator that reorders a collection of objects that implement the Comparable interface in the opposite direction of their natural ordering. It’s important to remember that we don’t call the reverseOrder() method directly. As shown below, we utilize it in conjunction with the collection.sort() method.

Collections.sort(objectOfArrayList, Collections.reverseOrder());

As a result, sorting an ArrayList in descending order is accomplished in two steps: first, the ArrayList sorts the data in ascending order, and then the reverseOrder() method reverses the sorted data. Let’s write some programs to sort the ArrayList in ascending order.

ArrayList sorted in ascending order

We’ve generated an ArrayList of type String and added some members to it in the following example. Then we passed the object of the ArrayList class, which is a list that sorts the elements in ascending order, to the sort() method of the Collections class.

Example 1: SortArrayList

import java.util.*;   
public class SortArrayList 
{   
  public static void main(String args[])   
  {   
    // creating object of ArrayList class  
    ArrayList<String> list = new ArrayList<String>();   
    // adding elements to the ArrayList   
    list.add("DELL");   
    list.add("HP");   
    list.add("Microsoft");   
    list.add("Apple");   
    list.add("Google ");   
    list.add("Air BnB");   
    list.add("Uber ");  
    list.add("Gitlab");  
    // printing the unsorted ArrayList   
    System.out.println("Before Sorting: "+ list);   
    // Sorting ArrayList in ascending Order   
    Collections.sort(list);   
    // printing the sorted ArrayList   
    System.out.println("After Sorting: "+ list);   
  }   
}  

Example 2: SortArrayList

import java.util.*;  

public class SortArrayList 
{  
  public static void main(String args[])  
  {  
    //creating an object of ArrayList class  
    ArrayList<Integer> listNumbers = new ArrayList<Integer>();  
    listNumbers.add(75);  
    listNumbers.add(52);  
    listNumbers.add(69);  
    listNumbers.add(85);  
    listNumbers.add(45);  
    listNumbers.add(60);  
    listNumbers.add(80);  
    //printing ArrayList before sorting  
    System.out.println("ArrayList Before Sorting:");  
    for(int marks: listNumbers)  
    {  
      System.out.println(marks);  
    }  
    //sorting ArrayList in ascending order  
    Collections.sort(listNumbers);  
    //printing ArrayList after sorting  
    System.out.println("ArrayList After Sorting:");  
    for(int marks: listNumbers)  
    {  
      System.out.println(marks);  
    }  
  }  
} 

ArrayList sorted in descending order

We’ve generated an ArrayList of type String and added some members to it in the following example. Then we passed the object of the ArrayList class, which is a list that sorts the elements in descending order, to the reverseOrder() and sort() methods of the Collections class.

Example: SortArrayList

import java.util.*;   
public class SortArrayListExample3  
{   
  public static void main(String args[])   
  {   
    // creating object of ArrayList class  
    ArrayList<String> languageList = new ArrayList<String>();   
    // adding elements to the ArrayList   
    languageList.add("HTML");   
    languageList.add("DotNet");   
    languageList.add("C");   
    languageList.add("Java");   
    languageList.add("Kotlin");   
    languageList.add("JavaScript ");   
    languageList.add("C++");  
    languageList.add("Python");  
    // printing the unsorted ArrayList   
    System.out.println("Before Sorting: "+ languageList);   
    // Sorting ArrayList in ascending Order   
    // using Collection.sort() method   
    Collections.sort(languageList, Collections.reverseOrder());   
    // Print the sorted ArrayList   
    System.out.println("After Sorting: "+ languageList);   
  }   
}  

Example: SortArrayList

import java.util.*;  
public class SortArrayListExample4   
{  
  public static void main(String args[])  
  {  
    //creating an object of ArrayList class  
    ArrayList<Integer> numList = new ArrayList<Integer>();  
    numList.add(123);  
    numList.add(562);  
    numList.add(251);  
    numList.add(356);  
    numList.add(410);  
    numList.add(124);  
    numList.add(368);  
    //printing ArrayList before sorting  
    System.out.println("ArrayList Before Sorting:");  
    for(int marks: numList)  
    {  
      System.out.println(marks);  
    }  
    //sorting ArrayList in descending order  
    Collections.sort(numList, Collections.reverseOrder());  
    //printing ArrayList after sorting  
    System.out.println("ArrayList After Sorting:");  
    for(int marks: numList)  
    {  
      System.out.println(marks);  
    }  
  }  
}  

Example: Sort an ArrayList in ascending order

The task is to sort an ArrayList in ascending order in Java, given an unsorted ArrayList. The sort() function of the Collections Class in Java is used to sort an ArrayList. This sort() function accepts a collection as an argument and produces a collection sorted by default in ascending order.

// Java program to demonstrate
// How to sort ArrayList in ascending order

import java.util.*;

public class Codeunderscored {
	public static void main(String args[])
	{

		// Get the ArrayList
		ArrayList<String> carsList = new ArrayList<String>();

		// Populate the ArrayList
		carsList.add("Toyota");
		carsList.add("BMW");
		carsList.add("Merceds-Benz");
		carsList.add("Suzuki");
		carsList.add("Tesla");

		// Print the unsorted ArrayList
		System.out.println("Unsorted ArrayList: "+ carsList);

		// Sorting ArrayList in ascending Order
		// using Collection.sort() method
		Collections.sort(carsList);

		// Print the sorted ArrayList
		System.out.println("Sorted ArrayList "
						+ "in Ascending order : "
						+ carsList);
	}
}

Example: ArrayList Sorting in Natural Order

import java.util.ArrayList;
import java.util.Comparator;

class Main {
  public static void main(String[] args) {

    // create an ArrayList
    ArrayList<String> compList = new ArrayList<>();

    // add elements to ArrayList
    compList.add("Software Engineer");
    compList.add("Backend Developer");
    compList.add("System Architect");
    compList.add("Mobile Engineer");
    System.out.println("Unsorted ArrayList: " + compList);

    // sort the ArrayList in ascending order
    compList.sort(Comparator.naturalOrder());

    System.out.println("Sorted ArrayList: " + compList);
  }
}

In the previous example, we used the sort() method to sort the ArrayList named languages. Take note of the line,

compList.sort(Comparator.naturalOrder());

The Java Comparator Interface’s naturalOrder() function indicates that elements are sorted in natural order (i.e., ascending order). In addition, the Comparator interface has a method for sorting components in descending order. As an example,

import java.util.ArrayList;
import java.util.Comparator;

class Main {
  public static void main(String[] args) {

    // create an ArrayList
    ArrayList<String> compList = new ArrayList<>();

    // add elements to ArrayList
   compList.add("Software Engineer");
    compList.add("Backend Developer");
    compList.add("System Architect");
    compList.add("Mobile Engineer");
    System.out.println("Unsorted ArrayList: " + compList);

    // sort the ArrayList in ascending order
    compList.sort(Comparator.reverseOrder());

    System.out.println("Sorted ArrayList: " + compList);
  }
}

The Comparator interface’s reverseOrder() function indicates that elements are sorted in reverse order (i.e., descending order). The Collections.sort() method is the more convenient option for sorting an ArrayList.

Using Comparables to Sort an ArrayList

The single important method in the Comparable interface is the compareTo() method. A Comparable-implemented object can compare itself to another Comparable-implemented object of the same type. The compareTo() method in the Ccmparable class has to be overridden.

This method takes an object of the same type as compareTo() and implements the logic for comparing it to the one passed in. The compareTo() method returns the comparison result as an integer. This object is greater than the object supplied to compareTo() if the value is positive. This object is less than the object supplied to compareTo() with a negative value. The number zero denotes equality between the two things.

Let’s look at a CodingStudent class with objects that we want to store in an ArrayList and then sort. The CodingStudent class includes three fields: a String name and gender and an integer age. We want to use the age attribute to sort the CodingStudent objects in the ArrayList. We’ll need to implement Comparable in the CodingStudent class and override the compareTo() method.

This is the CodingStudent class’s code.

// CodingStudent.java

package guru.springframework.blog.sortarraylist.comparable;     
public class CodingStudent implements Comparable<CodingStudent> {     
  private String name;     
  private String gender;     
  private int age;       
  public CodingStudent(String name, String gender, int age) {         
    this.name = name;         
    this.gender = gender;         
    this.age = age;     
 }       

  public String getName() {         
    return name;     
  }       

  public String getGender() {         
    return gender;     
  }                      

  public int getAge() {         
    return age;     
  }       

  @Override     
  public int compareTo( CodingStudent cStudent) {          
    return (this.getAge() < cStudent.getAge() ? -1 : 
            (this.getAge() == cStudent.getAge() ? 0 : 1));     
  }       

  @Override     
  public String toString() {         
    return " Name: " + this.name + ", Gender: " + this.gender + ", age:" + this.age;     
  } 
}

We built the comparison logic based on the age field in the override compareTo() method of the CodingStudent class above. Many programmers, in our experience, have reverted to the old method of returning the comparison result as:

 return (this.getAge() - cStudent.getAge());

Although utilizing this return statement may appear tempting and will have no effect on our example, we recommend that you avoid it. Consider the outcome of comparing integer values in which one or both are negative.

It might cause faults in your application that cause it to behave unpredictably, and because such bugs are subtle, they are tough to spot, especially in large business systems. Then, we’ll develop a helper class that sorts ArrayList objects containing CodingStudent elements for clients.

// CodingStudentSorter.java

package guru.springframework.blog.sortarraylist.comparable;     

import java.util.ArrayList; 
import java.util.Collections;   

public class CodingStudentSorter {     
  ArrayList<CodingStudent> codingStudent = new ArrayList<>();       

  public CodingStudentSorter(ArrayList<CodingStudent> codingStudent) {         
    this.codingStudent = codingStudent;     
  }       

  public ArrayList<CodingStudent> getSortedCodingStudentByAge() {         
    Collections.sort(codingStudent);         
    return codingStudent;     
  } 
}

We initialized an ArrayList object in the CodingStudentSorter class, which the client will give through the constructor when instantiating CodingStudentSorter. The getSortedCodingStudentByAge() method was then created. We passed the initialized ArrayList to Collections.sort() in this method. Finally, it returns the sorted ArrayList. After that, we’ll create a test class to put our code to the test.

CodingStudentSorterTest.java

package guru.springframework.blog.sortarraylist.comparable;   

import org.junit.Test;   
import java.lang.reflect.Array; 
import java.util.ArrayList;   
import static org.junit.Assert.*;     

public class CodingStudentSorterTest {       

  @Test     
  public void testGetSortedJobCandidateByAge() throws Exception {         
    CodingStudent codingStudent1 = new CodingStudent("Jane Smith", "Male", 46);         
    CodingStudent codingStudent2 = new CodingStudent("Ann Hunt", "Female", 53);         
    CodingStudent codingStudent3 = new CodingStudent("Mac Clark", "Female", 10);         
    CodingStudent codingStudent4 = new CodingStudent("Saint Styne", "Male", 74);         
    ArrayList<CodingStudent> codingStudentList = new ArrayList<>();       
  
    codingStudentList.add(codingStudent1);         
    codingStudentList.add(codingStudent2);         
    codingStudentList.add(codingStudent3);         
    codingStudentList.add(codingStudent4);       
  
    CodingStudentSorter codingStudentSorter = new CodingStudentSorter(codingStudentList);         
    ArrayList<CodingStudent> sortedCodingStudent = codingStudentSorter.getSortedCodingStudentByAge();         
    System.out.println("-----Sorted CodingStudent by age: Ascending-----");         
    for ( CodingStudent codingStudent : sortedCodingStudent ) {             
      System.out.println(codingStudent);    

We created four CodingStudent objects and added them to an ArrayList in the test class above. We then passed our ArrayList to the constructor of the CodingStudentSorter class. Finally, we invoked CodingStudentSorter’s getSortedJobCandidateByAge() method and printed the sorted ArrayList that the method returned.

Comparable is a typical method for sorting an ArrayList. However, you must be aware of some limitations. You must implement Comparable and override the compareTo() function in the class whose object you want to sort. It effectively means that you can only compare items based on one field (age in our example). What if your requirements specify that you must be able to sort CodingStudent objects by both name and age? Comparable isn’t the answer.

Furthermore, because comparison logic is part of the class whose objects must be compared, there is no way for the comparison logic to be reused. Java provides the Comparator interface in the Java.util package to satisfy such sorting comparison requirements.

Using a comparator to sort an ArrayList

The Comparator interface has only one comparison method called compare() like the Comparable interface. The compare() method, unlike the compareTo() method of Comparable, compares two separate objects of the same type.

The comparator will be used to rank items of the same CodingStudent class as before, but with a few variations. By creating Comparatoras anonymous inner classes, we will be able to sort CodingStudent objects by name and age.

The code for the CodingStudent class using comparator is shown below.

CodingStudent.java
package guru.springframework.blog.sortarraylist.comparator;     

import java.util.Comparator;   

public class CodingStudent {     
  private String name;     
  private String gender;     
  private int age;       

  public CodingStudent(String name, String gender, int age) {         
    this.name = name;         
    this.gender = gender;         
    this.age = age;     
  }       

  public String getName() {         
    return name;     
  }       

  public String getGender() {         
    return gender;     
  }       

  public int getAge() {         
    return age;     
  }       

  public static Comparator<CodingStudent> ageComparator = new Comparator<CodingStudent>() {         
    @Override         
    public int compare( CodingStudent cs1, CodingStudent cs2) {             
      return (cs2.getAge() < cs1.getAge() ? -1 :                     
              (cs2.getAge() == cs1.getAge() ? 0 : 1));           
    }     
  };       

  public static Comparator<CodingStudent> nameComparator = new Comparator<CodingStudent>() {         
    @Override         
    public int compare( CodingStudent cs1, CodingStudent cs2) {             
      return (int) (cs1.getName().compareTo(cs2.getName()));         
    }     
  };         

  @Override     
  public String toString() {         
    return " Name: " + this.name + ", Gender: " + this.gender + ", age:" + this.age;     
  } 
}

From Line 29 to Line 35 of the above class, we created an anonymous class and implemented the compare()method, which allows us to rank the CodingStudent objects by age in descending order.

We created another anonymous class and implemented the compare() method from Line 37 to Line 42, which allows us to rank CodingStudent objects by name in ascending order. We’ll now create a class that sorts the ArrayList’s elements for clients.

// CodingStudentSorter.java

package guru.springframework.blog.sortarraylist.comparator;     

import java.util.ArrayList; 
import java.util.Collections;                  

public class CodingStudentSorter {     
  ArrayList<CodingStudent> codingStudent = new ArrayList<>();       

  public CodingStudentSorter(ArrayList<CodingStudent> codingStudent) {         
    this.codingStudent = codingStudent;     
  }       

  public ArrayList<CodingStudent> getSortedCodingStudentByAge() {         
    Collections.sort(codingStudent, CodingStudent.ageComparator);         
    return codingStudent;     
  }       

  public ArrayList<JobCandidate> getSortedCodingStudentByName() {         
    Collections.sort(codingStudent, CodingStudent.nameComparator);         
    return codingStudent;     
  } 
}

The getSortedCodingStudentByAge() method was written in the previous class. We used the overloaded form of Collections in this method. sort() takes two arguments: an ArrayList object to sort and a Comparator object to compare age. We used the overloaded version of Collections again in the getSortedCodingStudentByName() method. sort() returns an ArrayList object sorted and a Comparator object used to compare names. Let’s create a test class to put our code to the test.

CodingStudentSorterTest.java

package guru.springframework.blog.sortarraylist.comparator;     

import guru.springframework.blog.sortarraylist.comparator.CodingStudent ; 
import guru.springframework.blog.sortarraylist.comparator.CodingStudentSorter; 

import org.junit.Before; 
import org.junit.Test;   
import java.util.ArrayList;   
import static org.junit.Assert.*;   

public class CodingStudentSorterTest {     
  CodingStudentSorter codingStudentSorter;       

  @Before     
  public void setUp() throws Exception {         
    CodingStudent codingStudent1 = new CodingStudent("Mark Smith", "Male", 26);         
    CodingStudent codingStudent2 = new CodingStudent("Sandy Hunt", "Female", 23);         
    CodingStudent codingStudent3 = new CodingStudent("Betty Clark", "Female", 20);         
    CodingStudent codingStudent4 = new CodingStudent("Andrew Styne", "Male", 24);         
    ArrayList<CodingStudent> codingStudentList = new ArrayList<>();         
    codingStudentList.add(codingStudent1);         
    codingStudentList.add(codingStudent2);         
    codingStudentList.add(codingStudent3);         
    codingStudentList.add(codingStudent4);         
    codingStudentSorter = new CodingStudentSorter(codingStudentList);     
  }       

  @Test     
  public void testGetSortedCodingStudentByAge() throws Exception {         
    System.out.println("-----Sorted CodingStudent by age: Descending-----");         
    ArrayList<CodingStudent> sortedCodingStudent = codingStudent Sorter.getSortedCodingStudentByAge();         
    for ( CodingStudent codingStudent : sortedCodingStudent ) {             
      System.out.println(codingStudent);         
    }     
  }       

  @Test     
  public void testGetSortedCodingStudentByName() throws Exception {         
    System.out.println("-----Sorted CodingStudent by name: Ascending-----");         
    ArrayList<CodingStudent> sortedCodingStudent = codingStudentSorter.getSortedCodingStudentByName();         
    for ( CodingStudent codingStudent : sortedCodingStudent) {             
      System.out.println(codingStudent);         
    }       
  } 
}

In the JUnit setup() method annotated with @Before, we populated CodingStudent objects in an ArrayList and generated a CodingStudentSorter object in the test class.

We invoked the getSortedCodingStudentByAge() method in the testGetSortedCodingStudentByAge() method and wrote out the sorted ArrayList that the function returns in thetestGetSortedCodingStudentByAge() method. The getSortedCodingStudentByName() function was called in the testGetSortedCodingStudentByName() test method, and the sorted ArrayList returned by the method was written out.

Conclusion

Because of its functionality and versatility, ArrayList is one of the most often used collection classes in the Java Collection Framework. ArrayList is a List implementation that uses a dynamic array to store elements internally. As a result, as you add and delete elements from an ArrayList, it can dynamically grow and decrease.

We’ve gone through one of the essential ArrayList operations that you’ll almost certainly need to use during corporate application development. It’s sorting an ArrayList’s elements.

We looked at various methods for sorting ArrayList members. One employs Comparable, whereas the other employs comparator. For programmers, the approach to choosing has always been a source of consternation. Essentially, a Comparable object can say, “I can compare myself to another object,” whereas a Comparator object can say, “I can compare two different objects.” It’s impossible to say that one interface is superior to the other. The interface you select is determined by the capabilities you require.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *