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);
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
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
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.
very good!
In future, Arrays class should provides more generic and handy method – Arrays.sort(Object, String, flag).
This is very bad design
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
Hai everyone,
Can I pass set implementation class object as parameter of sort() method like
Collections.sort(Set object ):
Need justify answer with proof…
((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) ?
Where to write main method in this program and how to call
Arrays.sort(fruits, fruitName, Arrays.ASCENDING); I tried but it is giving compile time error
CompareTo method not required in Fruit Class. As you are using String.CompareTo(String) not object.ComparTo(Object).
nice though ha…
Thanks! It help me!
made many stops here for reference. i love this write up. when i forget, i will just drop by here for reference. great writeup.
To compare with Strings, we can use the compareToIgnoreCase() method which returns a positive, negative or a 0 depending upon whether the first string has a greater, lesser or the same character as that of the second string. It is done through lexicographical comparison which means that the compareToIgnoreCase() method compares character by character starting from the left and as soon as it reaches a character which is different, it returns the corresponding values as stated above.
Here’s the code snippet of the overridden compareTo() method,
public int compareTo(Object obj)
{
Fruit fruit=(Fruit)obj;
return this.fruitName.compareToIgnoreCase(fruit.fruitName);
}
Thank you for clarifying the reason to use comparable and comparator. It is better to know why they are needed before the details of how to write the code. Thanks a lot!
Thank you so much. I understand very quickly.
Very good read, thank you!
When I want to sort an array of objects the object should implement the Comparable! If I want to compare using the Comparator should my class implements Comparable again?
I seriously appreciate your thought on
Arrays.sort(Object, String, flag).. it looks better this wayYour articles are fantastic! Thanks
Thanks @mkyong.
One comment : The statement, “The Fruit class contains a static FruitNameComparator method to compare the “fruitName”” is wrong. FruitNameComparator is a static instance variable of type Comparator in Fruit class. Also, I think it’s not mandatory for it to exist as a static member under Fruit, as this could be an equivalent:
class FruitComparator implements Comparator {
public int compare(Fruit f1, Fruit f2) {
return (f1.getFruitName().toUpperCase()).compareTo((f2.getFruitName().toUpperCase()));
}
}
Arrays.sort(fruits, new FruitNameComparator()); would be the call in the main method.
You are right Shishir, I also noticed the wrong sentence, and I totally agree with your alternative implementation proposal.
yes u r right……..
………
thats why mk said ClassCastException occurence
people you look on clear way……..
you are right. Additionally, If I am use sorting only at one place, I prefer giving the comparator implementation as an anonymous class.
Arrays.sort(fruits, new Comparator(){public int compare(Fruit f1, Fruit f2) {…}});
Here’s an open source library to sort multiple columns in a delimited string: https://sourceforge.net/projects/multicolumnrowcomparator/
if i don’ t know how many objects, i think would use List replacement for array[]
have the differences between use list and arrary[] ???
Awesome..!!! a simple and clear Explanation…just want to add one doesn’t need to implement Comparable Interface if they only want to use Comparator…
thanks Man..:))
I think it’s not this
Arrays.sort(fruits, Fruit.FruitNameComparator);
but this
Collections.sort(fruits, Fruit.FruitNameComparator);
isn’t collections used when using vector/arrayList?
fruits is an Array, not a List.
excellent, big thanks!
Man you rock!!!…
your implementation of comparator is very advanced so I didn’t understand it, however comparable was ok. could you please simplify it for me a total beginner to understand? If you don’t mind send your simplified version of comparator to [email protected]
Thanks for help.
Comparator is easy to understand but sometimes a bit confusing because of the difficult to grab documentation from oracle or earlier Sun. It is one of the most important things you need to know while working with java.
Try reading it here http://javahash.com/java-comparator-and-comparable-demystified/
That link was excellent thanks Prem kumar.
thank u
big thanks!!
thank you very much ..
that was really helpful 🙂
very well explained, thanks
Thanks, nicely explained!
I am just curious about the static fields used in the anonymous class instantiation: Should we put those static fields in a different class?
Or should they remain in the bean?
Thanks!
This is very useful for me thank u very much…………
why super() is used in Fruit class(no.3) ?
your Arrays.sort(fruits, fruitName, Arrays.ASCENDING); doesn’t make any sense, unless it is “fruitName” which is very unJava-like. Java 8 or 9 should provide lambdas, though to lessen the need for tons of ridiculously short classes such as Comparators.
I think your code (for comparator) is somewhat wrong. The class whose objects are to be sorted using compare() must implement Comparator, but u’ve only implemented Comparable.
>In future, Arrays class should provides more generic and handy method ? Arrays.sort(Object, String, flag).
OMG, desc is a mirrored asc, sort it asc, and mirror.
Thanks for giving this tutorial
Thank you man.
It wored perfectly for me even for the android.
Thank you sooooooooooo much
you deserve better!!!!
how to sort i language japan, china, korea?
how to sort in language japan, china, korea?
mkyong,
the problem with your code (sorting by value) yes it works on one platform but not on all. On eclipse I see error marks almost on every line of code but it still compiles. When I take it outside of eclipse it does not compile. The primary reason being parameter not specified.
i was looking for a lightweight and easy to understand implementation of comparable and comparator. Thanks a tonn for this.
what is the need of hascode&equals override..
the simple examle.
how to override the hashcode and equals().
fantastic!
Excellent…….
Very clear example. Thank you very much.
Sir,can you explaine me pseudocode for CompareTo() and Compare().
jj
That’s a nice example.
What if i want to sort my list in a specific order:
For example : The fruits should always be sorted as : banana, apple, pineapple, orange.
How compareTo() or comparable will work in such scenario ?
great!
Thanks a lot for this great post!.
I have a question. can we sort Object based on two attributes like name and ID at a single time? According to above example at a time we can sort eihter by id or name.
Thanks
Hi, in this compareTo method
public int compareTo(Fruit compareFruit)
you are passing an object of type Fruit.
And inside the method,
int compareQuantity = ((Fruit) compareFruit).getQuantity();
You are again casting the Fruit object to a Fruit data type…
Is it really necessary? Just compareFruit.getQuantity() should do the job i guess.
Sorry if i am wrong.
I think using generic may best solve your questions.
Yong,
I am following your posts since a month now.
I became a follower of you after seeing few posts.
I really appreciate your help to all Java developers. Each of these examples are very simple to understand and can be extended from then.
Raju Cherukuri
good artical….
thanks sir…
good post for all
nice article !!
Great explanation sir
thanks a lot
Nice explanation. This site has always been helpful. Good job!
While using Comparator, its better to declare them as nested class, It’s a good practice as shown in http://java67.blogspot.in/2012/10/how-to-sort-object-in-java-comparator-comparable-example.html
excellent example
“The Comparable interface is only allow to sort a single property.”
Wait, what? Properties can be compared one by one. If one of them, when compared, returns 0, we can proceed comparison.
Yes properties can be compared one by one but what if I want to sort based on fruitName and fruitDesc. Taking real life example of Employee object and sorting it based on id, name, salary etc.
BTW, we can create classes also for Comparator implementation, check it out http://www.journaldev.com/780/java-comparable-and-comparator-example-to-sort-objects
This example really helped me as these two comparable and comparator are very confusing.
But I have the following points:
1) Comparable can be used for int value value.
2) How can we use multiple fields sorting using comparator like Sorting on Country, State
and City order?
Can you please mail me the solution?
Hi Santosh, I also had a similar scenario as yours with the 1st question. It actually works with Object types. Therefore, you will not be able to do Collection.sort() instead you can use Arrays.sort(). However if you still want to use Collection.sort() with primitive types such as int,long & etc.. you can cast them to their wrapper classes for example Integer, Long and continue to use Collection.sort(). Thanks! 🙂
Two ways are for sorting using comparator and comparable. For detailed explanation is [here](http://sachinpatiljavablog.blogspot.in/2014/01/sorting-with-comparable-and-comparator.html)
Does comparator works the same for arrayList?
Does comparator works for arraylist too?
For sorting in reverse order , one can use Collections.reverseOrder() which returns a Compartor for reverse order .
source : http://javarevisited.blogspot.in/2011/06/comparator-and-comparable-in-java.html
Very nice…
Make me understand easy..
Thank you…..
Simple and clear explanation. Thanks 🙂
Just thanks!
Beautifully explained. Thanks.
Nice thanks.
this also can help
http://tobega.blogspot.com/2008/05/beautiful-enums.html
Sample :
Nice tutorial! Taught me what I needed to know to quickly implement a sort in my program.
One thing that might be useful for future readers is an explanation of this part of the code:
public int compareTo(Fruit compareFruit) { int compareQuantity = ((Fruit) compareFruit).getQuantity(); //ascending order return this.quantity - compareQuantity; //descending order //return compareQuantity - this.quantity; }It took me a minute to figure out what was going on here, especially since the fields I’m comparing are not integers, and this method requires an integer return type. The main idea, for those of you new to Comparable, is that to sort ascending, return a positive number (I returned +1) if this.quantity > compareQuantity. Return a negative number (-1) if this.quantity < compareQuantity. Return 0 if they are equal. (To sort descending, return -1, +1, and 0, respectively.)
My annotation lib for implementing Comparable and Comparator:
public class Person implements Comparable<Person> { private String firstName; private String lastName; private int age; private char gentle; @Override @CompaProperties({ @CompaProperty(property = "lastName"), @CompaProperty(property = "age", order = Order.DSC) }) public int compareTo(Person person) { return Compamatic.doComparasion(this, person); } }Click the link to see more examples.
http://code.google.com/p/compamatic/wiki/CompamaticByExamples
Thats! a pretty neat example….good effort!!