Introduction
In the real world, you will come across a situation where you need to sort an ArrayList of POJO. For example – Student, Department, Employee, and Payroll class objects. Sorting a list of objects is different than sorting a List of String or int. To sort an ArrayList of objects, you need two things –
- A class to provide an ordering.
- A method to provide sorting.
For this, Java already provides 2 classes Comparable
and Comparator
.
As the name suggests, Comparable is an interface defining a strategy of comparing an object with other objects of the same type. This is called the class’s “natural ordering”. e.g. lexicographic order of String or name for Student. Comparator is an interface that provides custom order. It gives you the flexibility to sort your objects on the parameter you want. For example, you can sort a list of Student objects on the Roll Number, Subject, Name.
Once you have your ordering of objects in place, you can use Java’s Collection.sort()
method to sort the objects in an ArrayList or List. This method accepts an ArrayList and sorts them in place. Internally, it uses MergeSort to sort your list of objects.
The JDK 8 added a couple of more methods on both java.util.Comparator
class and java.util.List
to make sorting easier. You can also use List.sort()
method to sort a List of objects. This method is similar to Collections.sort()
and you can use it to sort a List of objects using both Comparator and Comparable. This method accepts a Comparator and sort elements based upon that. In case, if you want to sort on the natural order, just don’t supply a Comparator and pass null.
1) Sort an Arraylist of Objects with Comparable
With Comparable
interface and compareTo()
method, we can sort using alphabetical order, String
length, reverse alphabetical order, or numbers. Here for our example, we’ll use the Student POJO that we have populated from the database. In this first example, we implement the Comparable interface in the Student
class.
package com.kodehelp.java.collection;
public class Student implements Comparable<Student> {
String name;
String course;
int rollNumber;
Student(String name, String course, int rollNumber ){
this.name = name;
this.course = course;
this.rollNumber = rollNumber;
}
@Override
public int compareTo(Student otherStudent) {
return this.name.compareTo(otherStudent.name);
}
}
package com.kodehelp.java.collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class StudentSorting {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Johnny", "C", 3));
students.add(new Student("Arnold", "Go", 8));
students.add(new Student("Ronald", "Java", 1));
students.add(new Student("Kevin", "R", 2));
students.add(new Student("George", "Scala", 10));
students.stream().map(s -> s.name).forEach(System.out::println);
System.out.println("\nSorting in natural order");
Collections.sort(students);
students.stream().map(s -> s.name).forEach(System.out::println);
System.out.println("\nSorting in Reverse order");
Collections.reverse(students);
students.stream().map(s -> s.name).forEach(System.out::println);
}
}
OUTPUT
Johnny
Arnold
Ronald
Kevin
George
Sorting in natural order
Arnold
George
Johnny
Kevin
Ronald
Sorting in Reverse order
Ronald
Kevin
Johnny
George
Arnold
Note that we’ve overridden the compareTo() method and passed in another
Student
object.
The compareTo()
method compares a given object or the current instance with a specified another object to determine the order of objects. Here’s a quick look at how compareTo()
works:
If the comparison returns | Then … |
---|---|
>=1 | this.name > student.name |
0 | this.name == student.name |
<= -1 | this.name < student.name |
We can only use classes that are comparable with the sort()
method. If we try to pass a Student
that does not implement Comparable
, we will receive a compilation error.
The sort()
method uses polymorphism by passing any object that is Comparable
. Objects will then be sorted as expected.
2) Sort an Arraylist of Objects with Comparator
You can sort an ArrayList of objects in both ascending and descending order by using Comparator. In the below example, I have a POJO called Student, which contains name as String and rollNumber as int value. I have created a Comparator for sorting by rollNumber. This Comparator implementation uses Java 8 lambdas to implement compare() method as shown here, and sort the list of objects into ascending order of rollNumber.
To sort in the reverse order i.e. descending order, you don’t need to create a separator Comparator, instead, you need to reverse the order of the existing comparator using Collections.reverseOrder(Comparator c)
method. If you are using Java 8, then you can also use the `reversed()` method of java.util.Comparator which returns a comparator that imposes the reverse ordering of this comparator.
package com.kodehelp.java.collection;
public class Student implements Comparable<Student> {
String name;
String course;
int rollNumber;
Student(String name, String course, int rollNumber ){
this.name = name;
this.course = course;
this.rollNumber = rollNumber;
}
@Override
public int compareTo(Student otherStudent) {
return this.name.compareTo(otherStudent.name);
}
@Override
public String toString() {
return String.format(name + " - " + rollNumber);
}
}
package com.kodehelp.java.collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class StudentSortWithComparator {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Johnny", "C", 3));
students.add(new Student("Arnold", "Go", 8));
students.add(new Student("Ronald", "Java", 1));
students.add(new Student("Kevin", "R", 2));
students.add(new Student("Karnav", "Scala", 10));
//Sort by rollnumber
Comparator<Student> rollNumberComparator = (s1,s2) -> (int)(s1.rollNumber - s2.rollNumber);
// printing ArrayList before sorting
System.out.println("unsorted list: ");
students.forEach(System.out::println);
// sorting arraylist of objects using comparator - using rollnumber on ascending order
students.sort(rollNumberComparator);
// printing ArrayList after sorting in ascending order
System.out.println("sorted list in ascending order of rollNumber: ");
students.forEach(System.out::println);
// sorting array list in descending order of title
students.sort(Collections.reverseOrder(rollNumberComparator));
System.out.println("sorted list in descending order of name: ");
students.forEach(System.out::println);
}
}
OUTPUT
unsorted list:
Johnny - 3
Arnold - 8
Ronald - 1
Kevin - 2
Karnav - 10
sorted list in ascending order of rollNumber:
Ronald - 1
Kevin - 2
Johnny - 3
Arnold - 8
Karnav - 10
sorted list in descending order of name:
Karnav - 10
Arnold - 8
Johnny - 3
Kevin - 2
Ronald - 1
That’s all about how to sort an ArrayList of Objects using Comparable and Comparator. You have learned to sort an ArrayList of Objects in both ascending and descending order using Comparable and Comparator.