Sort a list of objects using Comparable in Java
This post will discuss how to sort a list of objects using the Comparable in Java.
To sort a collection of objects (using some property) in Java, we can use the java.lang.Comparable interface, which imposes a natural ordering on the objects of each class that implements it. Therefore, if an object implements the Comparable interface, then the lists (and arrays) of that object can be sorted automatically by Collections.sort (and Arrays.sort).
Objects that implement this interface can also be used as keys in a sorted map (TreeMap) or as elements in a sorted set (TreeSet), without the need to specify a comparator.
This class’s implementer needs to override the abstract method compareTo() defined in java.util.Comparable, which compares the object with the specified object. The value returned by the compareTo() method decides the position of the object relative to the specified object.
- If
compareTo()returns a negative integer, the object is less than the specified object. - If
compareTo()returns a zero, the object is equal to the specified object. - If
compareTo()returns a positive integer, the object is greater than the specified object.
Here’s how we sort a list of Employee object using the Comparable interface in Java:
|
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 |
import java.util.*; class Employee implements Comparable<Employee> { private String name; private int age; public Employee(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + '}'; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Employee o) { return this.age - o.getAge(); } } class Main { public static void main(String[] args) { List<Employee> employees = new ArrayList<>(Arrays.asList( new Employee("John", 15), new Employee("Sam", 20), new Employee("Joe", 10) )); Collections.sort(employees); System.out.println(employees); } } |
Output:
[{name='Joe', age=10}, {name='John', age=15}, {name='Sam', age=20}]
The above code will sort the employee’s list only by the age field. If two employees have the same age, their relative ordering in the sorted list is not fixed. So, it is preferred to compare objects using multiple fields to avoid such cases.
How to compare objects against the multiple fields?
We can easily sort the employee’s list first by age and then by name, as shown below. Now for employees having the same age, the ordering is decided by the employee’s name.
|
1 2 3 4 5 6 7 |
@Override public int compareTo(Employee o) { if (this.age != o.getAge()) { return this.age - o.getAge(); } return this.name.compareTo(o.getName()); } |
Note that we have simply reduced the value of int primitive type age from each other while for the String object, built-in comparison method compareTo() is used. Typically, this chain can continue further to include other properties as well.
The complete code is demonstrated below:
|
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 |
import java.util.*; class Employee implements Comparable<Employee> { private String name; private int age; public Employee(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + '}'; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Employee o) { if (this.age != o.getAge()) { return this.age - o.getAge(); } return this.name.compareTo(o.getName()); } } class Main { public static void main(String[] args) { List<Employee> employees = new ArrayList<>(Arrays.asList( new Employee("John", 15), new Employee("Sam", 20), new Employee("Dan", 20), new Employee("Will", 20), new Employee("Joe", 10) )); Collections.sort(employees); System.out.println(employees); } } |
Output:
[{name='Joe', age=10}, {name='John', age=15}, {name='Dan', age=20}, {name='Sam', age=20}, {name='Will', age=20}]
⮚ Guava – ComparisonChain Class
We can use Guava’s ComparisonChain for performing a chained comparison statement inside the compareTo() method, as shown below:
|
1 2 3 4 5 6 7 |
@Override public int compareTo(Employee o) { return ComparisonChain.start() .compare(this.age, o.getAge()) .compare(this.name, o.getName()) .result(); } |
The return value of the compareTo() method would have the same sign as the first nonzero comparison result in the chain or will be zero if every comparison result was zero. Note that the ComparisonChain stops calling its inputs compareTo and compare methods as soon as one of them returns a nonzero result.
Here’s the complete code:
|
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 |
import com.google.common.collect.ComparisonChain; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; class Employee implements Comparable<Employee> { private String name; private int age; public Employee(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + '}'; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Employee o) { return ComparisonChain.start() .compare(this.age, o.getAge()) .compare(this.name, o.getName()) .result(); } } class Main { public static void main(String[] args) { List<Employee> employees = new ArrayList<>(Arrays.asList( new Employee("John", 15), new Employee("Sam", 20), new Employee("Dan", 20), new Employee("Will", 20), new Employee("Joe", 10) )); Collections.sort(employees); System.out.println(employees); } } |
Output:
[{name='Joe', age=10}, {name='John', age=15}, {name='Dan', age=20}, {name='Sam', age=20}, {name='Will', age=20}]
⮚ Using Apache Commons Lang
We can also use the CompareToBuilder class of the Apache Commons Lang library to assist in implementing the Comparable.compareTo(Object) methods. To use this class, write code as follows:
|
1 2 3 4 5 6 7 |
@Override public int compareTo(Employee o) { return new CompareToBuilder() .append(this.age, o.getAge()) .append(this.name, o.getName()) .toComparison(); } |
Values are compared in the order they are appended to the builder. If any comparison returns a nonzero result, then that value will be returned by toComparison(), and all subsequent comparisons are skipped.
Here’s the complete code:
|
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 |
import org.apache.commons.lang3.builder.CompareToBuilder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; class Employee implements Comparable<Employee> { private String name; private int age; public Employee(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + '}'; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Employee o) { return new CompareToBuilder() .append(this.age, o.getAge()) .append(this.name, o.getName()) .toComparison(); } } class Main { public static void main(String[] args) { List<Employee> employees = new ArrayList<>(Arrays.asList( new Employee("John", 15), new Employee("Sam", 20), new Employee("Dan", 20), new Employee("Will", 20), new Employee("Joe", 10) )); Collections.sort(employees); System.out.println(employees); } } |
Output:
[{name='Joe', age=10}, {name='John', age=15}, {name='Dan', age=20}, {name='Sam', age=20}, {name='Will', age=20}]
That’s all about sorting a list of objects using Comparable in Java.
Continue reading:
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)