Write a java program to sort an ArrayList of objects by field or property.
To understand the question first go through this example.
1 2 3 4 5 6 7 8 9 10 | Input: Object{ roll_no: 77, name: "Parshant" } Object{ roll_no: 41, name: "Anuj" } Object{ roll_no: 56, name: "Badal" } //Sorting by roll_no Output: Object{ roll_no: 41, name: "Anuj" } Object{ roll_no: 56, name: "Badal" } Object{ roll_no: 77, name: "Parshant" } |
To do the sorting according to a property we will need to implement the Comparator or Comparable interface.
But first, let’s start by sorting simple wrapper class objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import java.util.List; import java.util.ArrayList; import java.util.Collections; class Main { public static void main(String[] args) { List<Integer> roll_no = new ArrayList<>(); roll_no.add(41); roll_no.add(77); roll_no.add(56); System.out.println("Before Sorting: "); for(Integer x: roll_no){ System.out.print(x+" "); } //Sorting arraylist using sort() in Collections Framework Collections.sort(roll_no); System.out.println(" \nAfter Sorting: "); for(Integer x: roll_no){ System.out.print(x+" "); } } } |
1 2 3 4 | Before Sorting: 41 77 56 After Sorting: 41 56 77 |
Now let’s try the same with the objects of custom class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import java.util.List; import java.util.ArrayList; import java.util.Collections; class Student{ int roll_no; String name; Student(int roll_no, String name){ this.roll_no = roll_no; this.name = name; } public String toString(){ return "{ roll_no: "+roll_no+", name: "+name+" }"; } } class Main { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student(41, "Anuj")); students.add(new Student(77, "Parshant")); students.add(new Student(56, "Badal")); System.out.println("Before Sorting: "); for(Student x: students){ System.out.println(x); } //Sorting arraylist using sort() in Collections Framework Collections.sort(students); System.out.println(" \nAfter Sorting: "); for(Student x: students){ System.out.print(x); } } } |
1 2 3 4 5 6 7 8 | Main.java:33: error: no suitable method found for sort(List<Student>) Collections.sort(students); ^ method Collections.<T#1>sort(List<T#1>) is not applicable (inference variable T#1 has incompatible bounds equality constraints: Student lower bounds: Comparable<? super T#1>) method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable |
As you can see, the compiler gives an error stating that ‘the suitable method for sorting is not found’.
It is because we have not implemented the Comparable interface in the student class.
But why it worked for Integer wrapper class?
Because almost all wrapper classes such as Integer, Double, Float, String etc already have implemented the method of Comparable interface within them.
So let’s do the same for our custom Student class.
Sorting ArrayList using Comparable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import java.util.List; import java.util.ArrayList; import java.util.Collections; class Student implements Comparable<Student>{ int roll_no; String name; Student(int roll_no, String name){ this.roll_no = roll_no; this.name = name; } public String toString(){ return "{ roll_no: "+roll_no+", name: "+name+" }"; } //Override the compareTo() method of Comparable interface. public int compareTo(Student std2){ return this.roll_no - std2.roll_no; } } class Main { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student(41, "Anuj")); students.add(new Student(77, "Parshant")); students.add(new Student(56, "Badal")); System.out.println("Before Sorting: "); for(Student x: students){ System.out.println(x); } //Sorting arraylist using sort() in Collections Framework Collections.sort(students); System.out.println(" \nAfter Sorting: "); for(Student x: students){ System.out.println(x); } } } |
1 2 3 4 5 6 7 8 9 | Before Sorting: { roll_no: 41, name: Anuj } { roll_no: 77, name: Parshant } { roll_no: 56, name: Badal } After Sorting: { roll_no: 41, name: Anuj } { roll_no: 56, name: Badal } { roll_no: 77, name: Parshant } |
Sorting ArrayList using Comparator
The Student class objects can be sorted by individual field or property using the java.util.Comparator interface.
Collections.sort() takes the second argument as the instance of the class which implen=ments Comparator interface.
By implementing Comparator interfece we need to override the compare() method which accepts two user-defined type arguments(in our case is Student) and return an integer by comparing the objects by its property.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | import java.util.List; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; class Student{ int roll_no; String name; Student(int roll_no, String name){ this.roll_no = roll_no; this.name = name; } public String toString(){ return "{ roll_no: "+roll_no+", name: "+name+" }"; } //Override the compareTo() method of Comparable interface. public int compareTo(Student std2){ return this.roll_no - std2.roll_no; } public static Comparator<Student> nameComparator = new Comparator<>(){ public int compare(Student std1, Student std2){ return std1.name.compareTo(std2.name); } }; public static Comparator<Student> rollComparator = new Comparator<>(){ public int compare(Student std1, Student std2){ return std1.roll_no - std2.roll_no; } }; } class Main { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student(41, "Anuj")); students.add(new Student(37, "Parshant")); students.add(new Student(56, "Badal")); System.out.println("Before Sorting: "); for(Student x: students){ System.out.println(x); } //Sorting arraylist by default roll_no Collections.sort(students, Student.rollComparator); System.out.println(" \n Sorting by roll_no: "); for(Student x: students){ System.out.println(x); } //Sorting arraylist by name Collections.sort(students, Student.nameComparator); System.out.println(" \nSorting by name: "); for(Student x: students){ System.out.println(x); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Before Sorting: { roll_no: 41, name: Anuj } { roll_no: 37, name: Parshant } { roll_no: 56, name: Badal } Sorting by roll_no: { roll_no: 37, name: Parshant } { roll_no: 41, name: Anuj } { roll_no: 56, name: Badal } Sorting by name: { roll_no: 41, name: Anuj } { roll_no: 56, name: Badal } { roll_no: 37, name: Parshant } |
Comment below if you have any doubts or suggestion.