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.

The compareTo() method is hard to explain, in integer sorting, just remember

  1. this.quantity – compareQuantity is ascending order.
  2. 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
The java.lang.Comparable and java.util.Comparator are powerful but take time to understand and make use of it, may be it’s due to the lacking of detail example.

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);

Reference

  1. Comparable documentation
  2. Comparator documentation
author image

mkyong

Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities. Read all published posts by

Comments

avatar
newest oldest most voted
Arsen Khachatryan
Guest
Arsen Khachatryan

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

Milind Durugkar
Guest
Milind Durugkar

CompareTo method not required in Fruit Class. As you are using String.CompareTo(String) not object.ComparTo(Object).

andrey
Guest
andrey

very good!

trackback
Struts 2 Sort tag example

[…] Struts 2 sort tag is used to sort a List using a java.util.Comparator. In this tutorials, you will create 6 Person objects and add all into an ArrayList, and use the sort tag to sort the ArrayList based on the Person’s property. To use this Struts 2 sort tag, you have to understand how java.util.Comparator work, please read this article – Java object sorting with Comparator. […]

trackback
JSF 2 dataTable sorting example

[…] Java object sorting example This article was posted in JSF2 category. Oracle Magazine – Free Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for Java's developers and DBAs, and more. […]

trackback
sort according - Java Forums

[…] see examples in the link below. That should help you Java object sorting example (Comparable and Comparator) […]

bluec99
Guest
bluec99

Thats! a pretty neat example….good effort!!

Jianmin Liu
Guest
Jianmin Liu

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

LB
Guest
LB

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… Read more »

kvic
Guest
kvic

Nice thanks.

this also can help
http://tobega.blogspot.com/2008/05/beautiful-enums.html
Sample :

Collections.sort(myChildren, Child.Order.ByAge.descending());
Julie
Guest
Julie

Beautifully explained. Thanks.

Levan
Guest
Levan

Just thanks!

Baskar
Guest
Baskar

Simple and clear explanation. Thanks 🙂

vasanth
Guest
vasanth

Very nice…
Make me understand easy..
Thank you…..

Bhushan
Guest
Bhushan

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

trackback
JSF 2 dataTable sorting example – DataModel

[…] Java object sorting example This article is under – JSF 2 Tutorials , Tags : datatable jsf2 mkyong Founder and Chief Editor of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. […]

Melvin Yong
Guest
Melvin Yong

Does comparator works for arraylist too?

Melvin Yong
Guest
Melvin Yong

Does comparator works the same for arrayList?

santosh gupta
Guest
santosh gupta

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?

hamzeen.h.
Guest
hamzeen.h.

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! 🙂

Sachin P
Guest
Sachin P

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)

trackback
Making a game in a weekend… Can it be done? « TheInvader360

[…] across the solution (thank you internets!) My mistake was using comparable when I should have used comparator. I guess someone with more programming experience would have realised this immediately. A rookie […]

John Doe
Guest
John Doe

“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.

Pankaj
Guest
Pankaj

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

srinu
Guest
srinu

excellent example

Rohit
Guest
Rohit

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

Ruba
Guest
Ruba

Nice explanation. This site has always been helpful. Good job!

Rizwan
Guest
Rizwan

Great explanation sir

thanks a lot

devguy
Guest
devguy

nice article !!

raja
Guest
raja

thanks sir…
good post for all

pradip garala
Guest
pradip garala

good artical….

rajucherukuri
Guest
rajucherukuri

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

Abhilash
Guest
Abhilash

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.

benson
Guest
benson

I think using generic may best solve your questions.