ComparatorComperable

Java Comparable and Comparator Example to sort Objects

In Java, it’s very easy to sort an array or a list with primitive types. But you can also use Comparableand Comparator interfaces when you want to be able to short arrays or lists of your own custom objects.

Let’s begin with a very simple example using arrays of primitive types:

ObjectSortingExample.java:

package com.javacodegeeks.java.core;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ObjectSortingExample {

	public static void main(String[] args) {

		int[] integerArray = {1,0,3,2};

        Arrays.sort(integerArray);
        System.out.println(Arrays.toString(integerArray));

        String[] stringArray = {"J", "A", "V", "A", "C"};
        Arrays.sort(stringArray);
        System.out.println(Arrays.toString(stringArray));

        List stringList = new ArrayList();

        stringList.add("J");
        stringList.add("A");
        stringList.add("V");
        stringList.add("A");
        stringList.add("C");

        Collections.sort(stringList);
        for(String elem: stringList) System.out.print(" "+elem);
    }

}

The output of this program will be:

[0, 1, 2, 3]
[A, A, C, J, V]
 A A C J V

Now let’s try the same thing but with our own class.

Student.java:

package com.javacodegeeks.java.core;

public class Student {

	private int id;
	private String name;
	private int currentYearOfStudy;

	public Student(int id, String name, int currYearOfStudy) {
		this.id = id;
		this.name = name;
		this.currentYearOfStudy = currYearOfStudy;
	}

	public int getId() {
		return this.id;
	}

	public String getName() {
		return this.name;
	}

	public int getCurrentYearOfStudy() {
		return this.currentYearOfStudy;
	}

}

ObjectSortingExample.java:

package com.javacodegeeks.java.core;

import java.util.Arrays;

public class ObjectSortingExample {

	public static void main(String[] args) {

		Student[] studentArray = new Student[3];
		studentArray[0] = new Student(1, "Nikos",1);
		studentArray[1] = new Student(5, "Ilias", 4);
		studentArray[2] = new Student(4, "Byron", 5);

		Arrays.sort(studentArray);
		System.out.println(Arrays.toString(studentArray));

	}

}

The output of this will be:

Exception in thread "main" java.lang.ClassCastException: com.javacodegeeks.java.core.Student cannot be cast to java.lang.Comparable
	at java.util.ComparableTimSort.countRunAndMakeAscending(Unknown Source)
	at java.util.ComparableTimSort.sort(Unknown Source)
	at java.util.ComparableTimSort.sort(Unknown Source)
	at java.util.Arrays.sort(Unknown Source)
	at com.javacodegeeks.java.core.ObjectSortingExample.main(ObjectSortingExample.java:14)

And that is completely reasonable because Arrays.sort method has no clue on how to compare my objects. Somehow we have to give Arrays.sort a mechanism on how to compare my objects. To do that, we simply implement the generic Comparable<E> interface and override the compareTo method.

Student.java:

package com.javacodegeeks.java.core;

public class Student  implements Comparable<Student> {

	private int id;
	private String name;
	private int currentYearOfStudy;

	public Student(int id, String name, int currYearOfStudy) {
		this.id = id;
		this.name = name;
		this.currentYearOfStudy = currYearOfStudy;
	}

	public int getId() {
		return this.id;
	}

	public String getName() {
		return this.name;
	}

	public int getCurrentYearOfStudy() {
		return this.currentYearOfStudy;
	}

	@Override
	public String toString() {
		return "[id=" + this.id + ", name=" + this.name
				+ ", Current Year of Study=" + this.currentYearOfStudy + "]";
	}

	@Override
	public int compareTo(Student stud) {
		return (this.id - stud.id);
	}
}

ObjectSortingExample.java:

package com.javacodegeeks.java.core;

import java.util.Arrays;

public class ObjectSortingExample {

	public static void main(String[] args) {

		Student[] studentArray = new Student[3];
		studentArray[0] = new Student(1, "Nikos",1);
		studentArray[1] = new Student(5, "Ilias", 4);
		studentArray[2] = new Student(4, "Byron", 5);

		Arrays.sort(studentArray);
		System.out.println(Arrays.toString(studentArray));

	}

}

Now, as you might imagine, the Student will be sorted using the id field as a key. So the output of the above program would be:

[[id=1, name=Nikos, Current Year of Study=1], [id=4, name=Byron, Current Year of Study=5], [id=5, name=Ilias, Current Year of Study=4]]

Now image that a client code “A” requires that Student objects can be sorted using the name as key and client code “B” requires that Student objects can be sorted using currentYearOfStudy. To do that we have to define different Comperators. We will do that inside the Student class but you can also create another separate class with your own Comperators.

Student.java:

package com.javacodegeeks.java.core;

import java.util.Comparator;

public class Student implements Comparable<Student> {

	private int id;
	private String name;
	private int currentYearOfStudy;

	public Student(int id, String name, int currYearOfStudy) {
		this.id = id;
		this.name = name;
		this.currentYearOfStudy = currYearOfStudy;
	}

	public int getId() {
		return this.id;
	}

	public String getName() {
		return this.name;
	}

	public int getCurrentYearOfStudy() {
		return this.currentYearOfStudy;
	}

	@Override
	public String toString() {
		return "[id=" + this.id + ", name=" + this.name
				+ ", Current Year of Study=" + this.currentYearOfStudy + "]";
	}

	@Override
	public int compareTo(Student stud) {
		return (this.id - stud.id);
	}

	public static Comparator<Student> idComperator = new Comparator<Student>() {

		@Override
		public int compare(Student st1, Student st2) {
			return (int) (st1.getId() - st2.getId());
		}
	};

	public static Comparator<Student> currentYearComperator = new Comparator<Student>() {

		@Override
		public int compare(Student st1, Student st2) {
			return (int) (st1.getCurrentYearOfStudy() - st2.getCurrentYearOfStudy());
		}
	};

}

ObjectSortingExample.java:

package com.javacodegeeks.java.core;

import java.util.Arrays;

public class ObjectSortingExample {

	public static void main(String[] args) {

		Student[] studentArray = new Student[3];
		studentArray[0] = new Student(1, "Nikos",1);
		studentArray[1] = new Student(5, "Ilias", 4);
		studentArray[2] = new Student(4, "Byron", 5);

		Arrays.sort(studentArray, Student.idComperator);
		System.out.println("Using id as key :"+ Arrays.toString(studentArray));

		Arrays.sort(studentArray, Student.currentYearComperator);
		System.out.println("Using Current Year of Study as key :"+Arrays.toString(studentArray));

	}

}

The output of this program will be:

Using id as key :[[id=1, name=Nikos, Current Year of Study=1], [id=4, name=Byron, Current Year of Study=5], [id=5, name=Ilias, Current Year of Study=4]]

Using Current Year of Study as key :[[id=1, name=Nikos, Current Year of Study=1], [id=5, name=Ilias, Current Year of Study=4], [id=4, name=Byron, Current Year of Study=5]]

Of course you can further customize your Comperator and make it more complex. For example we will make a Comperator that will sort our objetc first by currentYearOfStudy and then by name:

Student.java:

package com.javacodegeeks.java.core;

import java.util.Comparator;

public class Student implements Comparable<Student> {

	private int id;
	private String name;
	private int currentYearOfStudy;

	public Student(int id, String name, int currYearOfStudy) {
		this.id = id;
		this.name = name;
		this.currentYearOfStudy = currYearOfStudy;
	}

	public int getId() {
		return this.id;
	}

	public String getName() {
		return this.name;
	}

	public int getCurrentYearOfStudy() {
		return this.currentYearOfStudy;
	}

	@Override
	public String toString() {
		return "[id=" + this.id + ", name=" + this.name
				+ ", Current Year of Study=" + this.currentYearOfStudy + "]";
	}

	@Override
	public int compareTo(Student stud) {
		return (this.id - stud.id);
	}

	public static Comparator<Student> idComperator = new Comparator<Student>() {

		@Override
		public int compare(Student st1, Student st2) {
			return (int) (st1.getId() - st2.getId());
		}
	};

	public static Comparator<Student> currentYearComperator = new Comparator<Student>() {

		@Override
		public int compare(Student st1, Student st2) {
			return (int) (st1.getCurrentYearOfStudy() - st2
					.getCurrentYearOfStudy());
		}
	};

	public static Comparator<Student> currentYearandNameComperator = new Comparator<Student>() {

		@Override
		public int compare(Student st1, Student st2) {
			int retval = (int) (st1.getCurrentYearOfStudy() - st2.getCurrentYearOfStudy());
			if (retval == 0) {
				retval = (int) (st1.getName().compareTo(st2.getName()));
			}
			return retval;
		}
	};

}

ObjectSortingExample.java:

package com.javacodegeeks.java.core;

import java.util.Arrays;

public class ObjectSortingExample {

	public static void main(String[] args) {

		Student[] studentArray = new Student[3];
		studentArray[0] = new Student(1, "Nikos",5);
		studentArray[1] = new Student(5, "Ilias", 4);
		studentArray[2] = new Student(4, "Byron", 4);

		Arrays.sort(studentArray, Student.currentYearAndNameComperator);
		System.out.println("Using Current Year and Name as key :"+ Arrays.toString(studentArray));	
	}
}

The output of this program will be:

Using Current Year and Name as key :[[id=4, name=Byron, Current Year of Study=4], [id=5, name=Ilias, Current Year of Study=4], [id=1, name=Nikos, Current Year of Study=5]]

This was a Comparable and Comparator Example to sort Objects in Java.

Byron Kiourtzoglou

Byron is a master software engineer working in the IT and Telecom domains. He is an applications developer in a wide variety of applications/services. He is currently acting as the team leader and technical architect for a proprietary service creation and integration platform for both the IT and Telecom industries in addition to a in-house big data real-time analytics solution. He is always fascinated by SOA, middleware services and mobile development. Byron is co-founder and Executive Editor at Java Code Geeks.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button