Java object sorting example (Comparable and Comparator)
In this tutorial, it shows the use of java.lang.Comparable and java.util.Comparator to sort a Java object based on its property value.
1. Sort an Array
To sort an Array, use the Arrays.sort().
String[] fruits = new String[] {"Pineapple","Apple", "Orange", "Banana"};
Arrays.sort(fruits);
int i=0;
for(String temp: fruits){
System.out.println("fruits " + ++i + " : " + temp);
}
Output
fruits 1 : Apple
fruits 2 : Banana
fruits 3 : Orange
fruits 4 : Pineapple
2. Sort an ArrayList
To sort an ArrayList, use the Collections.sort().
List<String> fruits = new ArrayList<String>();
fruits.add("Pineapple");
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Banana");
Collections.sort(fruits);
int i=0;
for(String temp: fruits){
System.out.println("fruits " + ++i + " : " + temp);
}
Output
fruits 1 : Apple
fruits 2 : Banana
fruits 3 : Orange
fruits 4 : Pineapple
3. Sort an Object with Comparable
How about a Java Object? Let create a Fruit class:
public class Fruit{
private String fruitName;
private String fruitDesc;
private int quantity;
public Fruit(String fruitName, String fruitDesc, int quantity) {
super();
this.fruitName = fruitName;
this.fruitDesc = fruitDesc;
this.quantity = quantity;
}
public String getFruitName() {
return fruitName;
}
public void setFruitName(String fruitName) {
this.fruitName = fruitName;
}
public String getFruitDesc() {
return fruitDesc;
}
public void setFruitDesc(String fruitDesc) {
this.fruitDesc = fruitDesc;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
To sort it, you may think of Arrays.sort() again, see below example :
package com.mkyong.common.action;
import java.util.Arrays;
public class SortFruitObject{
public static void main(String args[]){
Fruit[] fruits = new Fruit[4];
Fruit pineappale = new Fruit("Pineapple", "Pineapple description",70);
Fruit apple = new Fruit("Apple", "Apple description",100);
Fruit orange = new Fruit("Orange", "Orange description",80);
Fruit banana = new Fruit("Banana", "Banana description",90);
fruits[0]=pineappale;
fruits[1]=apple;
fruits[2]=orange;
fruits[3]=banana;
Arrays.sort(fruits);
int i=0;
for(Fruit temp: fruits){
System.out.println("fruits " + ++i + " : " + temp.getFruitName() +
", Quantity : " + temp.getQuantity());
}
}
}
Nice try, but, what you expect the Arrays.sort() will do? You didn’t even mention what to sort in the Fruit class. So, it will hits the following error :
Exception in thread "main" java.lang.ClassCastException:
com.mkyong.common.Fruit cannot be cast to java.lang.Comparable
at java.util.Arrays.mergeSort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
To sort an Object by its property, you have to make the Object implement the Comparable interface and override the compareTo() method. Lets see the new Fruit class again.
public class Fruit implements Comparable<Fruit>{
private String fruitName;
private String fruitDesc;
private int quantity;
public Fruit(String fruitName, String fruitDesc, int quantity) {
super();
this.fruitName = fruitName;
this.fruitDesc = fruitDesc;
this.quantity = quantity;
}
public String getFruitName() {
return fruitName;
}
public void setFruitName(String fruitName) {
this.fruitName = fruitName;
}
public String getFruitDesc() {
return fruitDesc;
}
public void setFruitDesc(String fruitDesc) {
this.fruitDesc = fruitDesc;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int compareTo(Fruit compareFruit) {
int compareQuantity = ((Fruit) compareFruit).getQuantity();
//ascending order
return this.quantity - compareQuantity;
//descending order
//return compareQuantity - this.quantity;
}
}
The new Fruit class implemented the Comparable interface, and overrided the compareTo() method to compare its quantity property in ascending order.
- this.quantity – compareQuantity is ascending order.
- compareQuantity – this.quantity is descending order.
To understand more about compareTo() method, read this Comparable documentation.
Run it again, now the Fruits array is sort by its quantity in ascending order.
fruits 1 : Pineapple, Quantity : 70
fruits 2 : Orange, Quantity : 80
fruits 3 : Banana, Quantity : 90
fruits 4 : Apple, Quantity : 100
4. Sort an Object with Comparator
How about sorting with Fruit’s “fruitName” or “Quantity”? The Comparable interface is only allow to sort a single property. To sort with multiple properties, you need Comparator. See the new updated Fruit class again :
import java.util.Comparator;
public class Fruit implements Comparable<Fruit>{
private String fruitName;
private String fruitDesc;
private int quantity;
public Fruit(String fruitName, String fruitDesc, int quantity) {
super();
this.fruitName = fruitName;
this.fruitDesc = fruitDesc;
this.quantity = quantity;
}
public String getFruitName() {
return fruitName;
}
public void setFruitName(String fruitName) {
this.fruitName = fruitName;
}
public String getFruitDesc() {
return fruitDesc;
}
public void setFruitDesc(String fruitDesc) {
this.fruitDesc = fruitDesc;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int compareTo(Fruit compareFruit) {
int compareQuantity = ((Fruit) compareFruit).getQuantity();
//ascending order
return this.quantity - compareQuantity;
//descending order
//return compareQuantity - this.quantity;
}
public static Comparator<Fruit> FruitNameComparator
= new Comparator<Fruit>() {
public int compare(Fruit fruit1, Fruit fruit2) {
String fruitName1 = fruit1.getFruitName().toUpperCase();
String fruitName2 = fruit2.getFruitName().toUpperCase();
//ascending order
return fruitName1.compareTo(fruitName2);
//descending order
//return fruitName2.compareTo(fruitName1);
}
};
}
The Fruit class contains a static FruitNameComparator method to compare the “fruitName”. Now the Fruit object is able to sort with either “quantity” or “fruitName” property. Run it again.
1. Sort Fruit array based on its “fruitName” property in ascending order.
Arrays.sort(fruits, Fruit.FruitNameComparator);
Output
fruits 1 : Apple, Quantity : 100
fruits 2 : Banana, Quantity : 90
fruits 3 : Orange, Quantity : 80
fruits 4 : Pineapple, Quantity : 70
2. Sort Fruit array based on its “quantity” property in ascending order.
Arrays.sort(fruits)
Output
fruits 1 : Pineapple, Quantity : 70
fruits 2 : Orange, Quantity : 80
fruits 3 : Banana, Quantity : 90
fruits 4 : Apple, Quantity : 100
My thoughts…
In future, Arrays class should provides more generic and handy method – Arrays.sort(Object, String, flag).
To sort a object array by its “fruitName” in ascending order.
Arrays.sort(fruits, fruitName, Arrays.ASCENDING);
To sort a object array by its “quantity” in ascending order.
Arrays.sort(fruits, quantity, Arrays.DESCENDING);
Good example,
How you will compare the list which has two string properties. For example:
List dataList = new ArrayList();
Data d = new Data();
d.setCode(“CH”);
d.setDisplayValue(“C value”);
dataList.add(d);
d = new Data();
d.setCode(“AH”);
d.setDisplayValue(“A value”);
dataList.add(d);
d = new Data();
d.setCode(“B0”);
d.setDisplayValue(“B value”);
dataList.add(d);
d = new Data();
d.setCode(“B1”);
d.setDisplayValue(“B1 value”);
dataList.add(d);
d = new Data();
d.setCode(“DH”);
d.setDisplayValue(“D value”);
dataList.add(d);
How can you sort by display value (DisplayValue)?
Thanks in advance
very good!
CompareTo method not required in Fruit Class. As you are using String.CompareTo(String) not object.ComparTo(Object).
Thanks a lot, hoho
please help on developing the spring boot application for a fruit store market. requirement is to develop an inventory that manages the stock of fruits and aging of the fruits , managing the damaged fruits etc..
Very well explained
If ur class is Employee and the three parameter in this class like name, name, salary
1. If you want to sort by name then you can use first Compairable interface like:
class Employee implements Compairable{
public Employee (String name, String age, int salary) {
super();
this.name= name;
this.age= age;
this.salary= salary;
}
String name;
int age;
double salary;
public int compareTo(Employee employee) {
return this.name.equalsIgnoreCase(employee.getname());
}
}
Employee employee = new Employee (“a”,25,9000);
Note: No need to pass this in sort method.
2.If also you have requirement to sort by age then you can create Agecomparator class and you can use this age comparator like:
Agecomparator implements Comparator() {
public int compare(Employee emp1, Employee emp2) {
if(emp1>emp2){
return 1;
}else if(emp1<emp2){
return -1;
}else ifemp1==emp2){
return 0;
}
return fruitName1.compareTo(fruitName2);
}
}
Collections.sort(list, Agecomparator).
Note : if you need sortting according multiple bases like age, salary etc then you can use Comparator.
good article
how do u apply this to a textfile?
Nice!!!
Please update the link to ‘Comparable Docum…’ (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Comparable.html)
Beautiful example! Thanks
((Fruit) compareFruit).getQuantity() whats going here iam not understood
its type casting but no need to type cast compareFruit in Fruit because its already Fruit object.
how can we sort this Object Arraylist
ArrayList objt = new ArrayList();
objt.add(4);
objt.add(5);
objt.add(6);
objt.add(1);
Hi,
Can you tell me what is this ? Why it is used ?
And How this works ?
//ascending order
return fruitName1.compareTo(fruitName2);
//descending order
//return fruitName2.compareTo(fruitName1);
The doc reference link is broken.
Since Comparator is a functional interface so we can use lambda expression to provide implementation of its abstract method. That will reduce the custom comparator implementation to a single line. Don’t forget to import the comparator interface though.
As example if I have list of coties cityList then it can be sorted using lambda expression this way
Collections.sort(cityList, (String a, String b)-> b.compareTo(a));
Read more here – http://netjs.blogspot.in/2015/08/how-to-sort-arraylist-in-java.html
Actually limitation with comparable has to do with natural ordering which you have already defined for your class … If you want your collection to be sorted in any other way, than the natural ordering you have defined, then you have to write a comparator.
See my post too – http://netjs.blogspot.in/2015/08/how-to-sort-arraylist-of-custom-objects-java.html
this is the best web of blog what ever for java tutorial
The best ever site …..for self learner
can comparator instances be public ?
This is off-topic but why do you use an int and a for-each loop in most of your examples?
Like the following:
int i=0;
for(String temp: fruits) {
System.out.println(“fruits ” + ++i + ” : ” + temp);
}
Why not just use a regular old for loop?
for(int i=0; i<fruits.length; i++) {
System.out.println("fruits " + i + " : " + fruits[i].toString());
}
Thank you mkyong. It was very useful 🙂
would like to know…internally what sorting technique is used when we use comparable or comparator to compare objects in collection
thank you for sharing this tutorial , it is great 🙂
Thank you very much, your guide was really helpful
To the point explanation
Thanks
Thank so very much! I used this to great value in a project where I needed to sort Edges of a graph by their numeric label, and later on I needed to topologically sort the whole graph, so I defined a comparator that sorted by postvisit time. Works like a charm.
Shouldn’t it be: public int compareTo(Object fruit){…} in order it inherits the compareTo-method?
This class implements the Comparator interface. You should consider whether or not it should also implement the Serializable interface. If a comparator is used to construct an ordered collection such as a TreeMap, then the TreeMap will be serializable only if the comparator is also serializable. As most comparators have little or no state, making them serializable is generally easy and good defensive programming.
findbugs SE_COMPARATOR_SHOULD_BE_SERIALIZABLE
why super() is used in Fruit class(no.3) ?