How to sort a list of user-defined objects in Java

In this shot, we will look at methods to sort a list of user-defined objects. We will cover the following techniques:

  1. How to implement Comparable interface
  2. How to implement Comparator interface
  3. How to use streams in Java
class Student {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

Consider the above Student class, which has name and age as data members. We are given a list of student objects that need to be sorted by the age attribute:

Student s1 = new Student("student-1", 12);
Student s2 = new Student("student-2", 24);
Student s3 = new Student("student-3", 36);
List<Student> studentList = Arrays.asList(s2, s1, s3);

Implement the Comparable interface

The Student class can be modified to implement the Comparable interface, which provides a compareTo() method, where the logic of comparison is written. We can use Collections.sort() to sort the list of the students. If the sorting has to be done in reverse order, change the logic in the compareTo() method.

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Main {
static class Student implements Comparable < Student > {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student student) {
return this.age - student.age;
}
}
public static void main(String[] args) {
Student s1 = new Student("student-1", 12);
Student s2 = new Student("student-2", 24);
Student s3 = new Student("student-3", 36);
List < Student > studentList = Arrays.asList(s2, s1, s3);
System.out.println("Before sorting");
System.out.println(studentList);
Collections.sort(studentList);
System.out.println("After sorting");
System.out.println(studentList);
}
}

Implement the Comparator interface

We can create another class for the comparison of age that implements the Comparator interface without the modification of the Student class.

This way of sorting allows us the flexibility to sort different data members of the class without the modification of existing classes.

Implementing the Comparator interface means the compare method has to be overridden where the logic for the comparison is implemented.

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
static class Student {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
static class StudentAgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
public static void main(String[] args) {
Student s1 = new Student("student-1", 12);
Student s2 = new Student("student-2", 24);
Student s3 = new Student("student-3", 36);
List < Student > studentList = Arrays.asList(s2, s1, s3);
System.out.println("Before sorting");
System.out.println(studentList);
Collections.sort(studentList, new StudentAgeComparator());
System.out.println("After sorting");
System.out.println(studentList);
}
}

Similarly, we can create another class for comparison by name.

class StudentNameComparator implements Comparator<Student> {

        @Override
        public int compare(Student o1, Student o2) {
            return o1.name.compareTo(o2.name);
        }
}

Use Streams in Java

We can create a stream out of the list of the objects and use the sorted() method on the stream that takes in a class that implements a Comparator interface.

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
class HelloWorld {
static class Student {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
static class StudentAgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
public static void main(String[] args) {
Student s1 = new Student("student-1", 12);
Student s2 = new Student("student-2", 24);
Student s3 = new Student("student-3", 36);
List<Student> studentList = Arrays.asList(s2, s1, s3);
List<Student> sortedStudentList = studentList.stream().sorted(new StudentAgeComparator()).collect(Collectors.toList());
System.out.println(sortedStudentList);
}
}

Free Resources