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

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
Priya
Guest
Priya

Very informative article. I am little confuse about comparable & comparator but now i have clear idea about it.

ankit
Guest
ankit
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… Read more »
Milind Durugkar
Guest
Milind Durugkar

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

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

andrey
Guest
andrey

very good!

elvis
Guest
elvis

good article

Budulla Akhlaaq
Guest
Budulla Akhlaaq

how do u apply this to a textfile?

Hidayath
Guest
Hidayath

Nice!!!
Please update the link to ‘Comparable Docum…’ (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Comparable.html)

Luki R Daniel
Guest
Luki R Daniel

Beautiful example! Thanks

Rajakumar
Guest
Rajakumar

Hai everyone,

Can I pass set implementation class object as parameter of sort() method like
Collections.sort(Set object ):
Need justify answer with proof…

kammiti krishna
Guest
kammiti krishna

((Fruit) compareFruit).getQuantity() whats going here iam not understood

ankit
Guest
ankit

its type casting but no need to type cast compareFruit in Fruit because its already Fruit object.

akash rathod
Guest
akash rathod

how can we sort this Object Arraylist

ArrayList objt = new ArrayList();

objt.add(4);
objt.add(5);
objt.add(6);
objt.add(1);

Leo Messi
Guest
Leo Messi

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

Rohan Sethi
Guest
Rohan Sethi

The doc reference link is broken.

infoj
Guest
infoj

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

infoj
Guest
infoj

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

Raihan Uddin Maksud
Guest
Raihan Uddin Maksud

this is the best web of blog what ever for java tutorial

manas ranjan dhal
Guest
manas ranjan dhal

The best ever site …..for self learner

Deo Priya
Guest
Deo Priya

can comparator instances be public ?

AnonyMouse
Guest
AnonyMouse

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

Sridhar.Goranti
Guest
Sridhar.Goranti

Thank you mkyong. It was very useful :)

Mahadev
Guest
Mahadev

would like to know…internally what sorting technique is used when we use comparable or comparator to compare objects in collection

kuku
Guest
kuku

thank you for sharing this tutorial , it is great :)

Andrea
Guest
Andrea

Thank you very much, your guide was really helpful

Vivek Pal
Guest
Vivek Pal

To the point explanation
Thanks

Chris
Guest
Chris

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.

Ramtin
Guest
Ramtin

Shouldn’t it be: public int compareTo(Object fruit){…} in order it inherits the compareTo-method?

JJ
Guest
JJ

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

nisha
Guest
nisha

why super() is used in Fruit class(no.3) ?

Rahul
Guest
Rahul

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

Ram
Guest
Ram

nice though ha…