You are on page 1of 12

Sorting Collection Elements

Use one of the following overloaded methods from Collections class to sort List elements explicitly:
Public static void sort(List)
Public static void sort(List, Comparator)
By default, none of the List implementation classes are sorted.
To sort list elements, use one of the following interfaces:
a) Java.lang.Comparable
b) Java.util.Comparator

Comparable <<interface>>
It is used for providing Natural sorting order.
This interface is available in java.lang package. This interface contains only one method compareTo().
public int compareTo(Object O);
obj1.compareTo (obj2);
Return ve then obj1 is placed before obj2.
Return +ve then obj1 is placed after obj2.
Returns 0 then obj1 and obj2 are equal.
All wrapper and String classes are inherited from Comparable interface. Hence, natural sorting order is built-in
for these classes.
Example #1: Natural sorting order for Built-In String class.
import java.util.Collections;
import java.util.List;
import java.util.Vector;
public class StringSort {
public static void main(String[] args) {
List alphabets = new Vector();
alphabets.add("C");
alphabets.add("A");
alphabets.add("B");
System.out.println(alphabets);
Collections.sort(alphabets);//Natural sorting order
System.out.println(alphabets);
}
1

}
Example #2: Natural sorting order for User Defined classes.
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
class Student implements Comparable {
int sno;
String sname;
int age;
Student() { }
Student(int sno, String sname, int age) {
this.sno = sno;
this.sname = sname;
this.age = age;
}
// natural sorting order.
public int compareTo(Object o) {
Student sRef = null;
If(o == null)
throw new NullPointerException();
if (!(o instanceof Student)) {
throw new ClassCastException();
}
sRef = (Student) o;
if (this.sno < sRef.sno)
return -1;
else if (this.sno > sRef.sno)
return 1;
else
return 0;
}
}
public class StudentSort {
public static void main(String... args) {
Student s1 = new Student(2, "NTR", 27);
Student s2 = new Student(1, "CHIRU", 48);
Student s3 = new Student(3, "BALU", 47);

List list = new Vector();


list.add(s1);
list.add(s2);
list.add(s3);
// Display elements before sorting
System.out.println("Before sorting..");
Iterator ittr = list.iterator();
while (ittr.hasNext()) {
Student s = (Student) ittr.next();
System.out.println(s.sno);
}
//Sort collection elements.
Collections.sort(list);
// Display elements after sorting
System.out.println("After sorting...");
ittr = list.iterator();
while (ittr.hasNext()) {
Student s = (Student) ittr.next();
System.out.println(s.sno);
}
}
}
Whenever we are depending on natural sorting order internally JVM automatically calls compareTo() method, to
place all objects in sorting order.
Limitations with Comparable interface:
1) We cannot provide sorting order for non-comparable built-in classes such as StringBuffer.
2) We cannot provide multiple sorting techniques other than natural sorting order for both built-in and
user defined classes.
3) We cannot provide different sorting order other than natural sorting order for built-in comparable
classes such as String, Integer, etc.
4) We cannot sort heterogeneous elements using Comparable interface.

Comparator <<interface>>
This interface is available in java.util package.
Comparator interface is used to provide customized sorting order.
The customized sorting order is required for following scenarios:

1) To provide sorting order for non-comparable built-in classes such as StringBuffer i.e., built-in classes
which are not inherited from Comparable interface.
Example:
StringBuffer which is not inherited from Comparable interface. Hence, to sort string buffer
objects, Comparator interface must be used.
2) To provide multiple sorting techniques for both built-in and user-defined classes.
Example:
a) Sort students based on roll number. OR
b) Sort students based on student name. OR
c) Sort students based on Student age.
3) To provide different sorting techniques other than natural sorting order for built-in Comparable classes.
Example:
a) Sort strings in descending order.
b) Sort integers in descending order.
4) To sort Heterogeneous elements.
For example, if the collection contains both String and StringBuffer objects.
Methods:
Comparator interface contains the following two methods:
1. Public int compare(Object obj1, Object obj2);
Return ve then obj1 is placed before obj2.
Return +ve then obj1 is placed after obj2.
Returns 0 then obj1 and obj2 are equal.
2. Public Boolean equals(Object obj);
Whenever we implement Comparator interface, compulsory we should provide implementation for the
compare() method.
Implementing equals()method is optional, since it is already available in Object class.
Case 1: Provide sorting order for non-comparable built-in classes such as StringBuffer.
Example:
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Vector;
class MyComparator implements Comparator{
public int compare(Object o1, Object o2) {
String str1 = o1.toString();
String str2 = o2.toString();
return str1.compareTo(str2);
}
}
4

public class ComparatorDemo1 {


public static void main(String[] args) {
StringBuffer sb1 = new StringBuffer("A");
StringBuffer sb2 = new StringBuffer("Z");
StringBuffer sb3 = new StringBuffer("C");
Vector v = new Vector();
v.add(sb1);
v.add(sb2);
v.add(sb3);
// Collections.sort(v); //throws C.C.E since collection elements are non comparable.
Collections.sort(v, new MyComparator());
System.out.println("After sorting....");
System.out.println(v.toString());
}
}
O/P:
After sorting....
[A, C, Z]

ClassCastException w.r.t Collections.sort() method:


I.

II.

The Collections.sort(List) utility method throws ClassCastException when collection elements are non
comparable.
Example:
StringBuffer sb1 = new StringBuffer(one);
StringBuffer sb2 = new StringBuffer(two);
Vector v = new Vector();
v.add(sb1); v.add(sb2);
Collections.sort(v);
//throws C.C.E
The Collections.sort(List) utility method throws ClassCastException though collection elements
comparable but different.
Example:
String str = new String(ten);
Integer iRef = 10;
Vector v = new Vector();
v.add(str);
v.add(iRef);
Collections.sort(v); // C.C.E
Overall scenarios which likely to throw ClassCastException:
1) Assigninig supertype object to subtype reference variable.
2) Unrelated object and reference types.
3) Non homogeneous comparable elements in sorted collections.
4) Non comparable classes such as StringBuffer for sorted
collections.

Case 2: Provide multiple sorting techniques for both built-in and user defined classes.
Example#1: Sort Employees based on employee number using natural sorting order.
//Natural sorting order..
class Employee implements Comparable {
int eno;
String ename;
int sal;
Employee(int eno, String ename, int sal) {
this.eno = eno;
this.ename = ename;
this.sal = sal;
}
public int compareTo(Object o) {
Integer iRef1 = this.eno;
Integer iRef2 = ((Employee)o).eno;
return iRef1.compareTo(iRef2);
}
Public String toString(){
Return Eno=+eno+ Ename=+ename+ Salary=+sal;
}
}
Example#2: Sort employees based on employee names in ascending order.
// Sort employees based on ename in ascending order.
class NameComparator implements Comparator {
public int compare(Object arg0, Object arg1) {
String str1 = ((Employee)arg0).ename;
String str2 = ((Employee)arg1).ename;
return str1.compareTo(str2);
}
}
Example#3: Sort employees based on employee names in descending order.
// sort employees based on ename in descending order.
class NameComparatorDes implements Comparator {
6

public int compare(Object arg0, Object arg1) {


String str1 = ((Employee)arg0).ename;
String str2 = ((Employee)arg1).ename;
return -str1.compareTo(str2);
// return str2.compareTo(str1);
}
}
Example#4: Sort employees based on employee salary.
// sort employees based on salary.
class SalaryComparator implements Comparator {
public int compare(Object arg0, Object arg1) {
Integer iRef1 = ((Employee) arg0).sal;
Integer iRef2 = ((Employee) arg1).sal;
return iRef1.compareTo(iRef2);
}
}
//Client code.
public class ComparatorDemo2 {
public static void main(String... args) {
Employee e1 = new Employee(1,"Bill Gates",100000);
Employee e2 = new Employee(3,"Mukesh",1500000);
Employee e3 = new Employee(2,"Ratan",1000000);
Vector v = new Vector();
v.add(e1);
v.add(e2);
v.add(e3);
//sort employees based on eno
Collections.sort(v);//internally invokes compareTo() method.
System.out.println("sort based on eno");
for(Object o: v){
Employee e = (Employee)o;
System.out.println(e.toString());
}
//sort employees based on ename in ascending order.
Collections.sort(v,new NameComparator());
System.out.println("sort based on enane in ascending order...");
7

for(Object o: v){
Employee e = (Employee)o;
System.out.println(e.toString());
}
//sort employees based on ename in descending order.
Collections.sort(v, new NameComparatorDes());
System.out.println("sort based on enane in descending order...");
for(Object o: v){
Employee e = (Employee)o;
System.out.println(e.toString());
}
//sort employees based on salary.
Collections.sort(v, new SalaryComparator());
System.out.println("sort based on sal ...");
for(Object o: v){
Employee e = (Employee)o;
System.out.println(e.toString());
}
}
}
O/P:
sort based on eno
1
Bill Gates
100000
2
Ratan 1000000
3
Mukesh1500000
sort based on enane in ascending order...
1
Bill Gates
100000
3
Mukesh1500000
2
Ratan 1000000
sort based on enane in descending order...
2
Ratan 1000000
3
Mukesh1500000
1
Bill Gates
100000
sort based on sal ...
1
Bill Gates
100000
2
Ratan 1000000
3
Mukesh1500000
Case 3: Provide sorting technique other than natural sorting order for built-in comparable classes.
8

Example#1: Sort string elements in descending order.


//Descending order
class StringDescendingOrder implements Comparator{
public int compare(Object o1, Object o2) {
String str1 = o1.toString();
String str2 = o2.toString();
return str1.compareTo(str2);
}
}
//Client code
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;
public class ComparatorDemo3 {
public static void main(String[] args) {
String s1 = "A";
String s2 = "C";
String s3 = "B";
List list = new Vector();
list.add(s1);
list.add(s2);
list.add(s3);
Collections.sort(list); //Natural sorting order.
System.out.println("Ascending Order:");
System.out.println(list.toString());
//O/P: [A, B, C]
Collections.sort(list, new StringDescendingOrder()); //Descending order
System.out.println("Descending Order:");
System.out.println(list.toString());
//O/P: [C, B, A]
}
}
Example#2: Sort integer elements in descending order.
//Descending order
class IntegerDescendingOrder implements Comparator{
public int compare(Object o1, Object o2) {
Integer iRef1 = (Integer)o1;
9

Integer iRef2 = (Integer)o2;


/*if(iRef1 < iRef2){
return 1;
}else if(iRef1 > iRef2){
return -1;
}else return 0;*/
return iRef2.compareTo(iRef1);
}
}
//Client code
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;
public class ComparatorDemo4 {
public static void main(String[] args) {
Integer iRef1 = 20;
Integer iRef2 = 10;
Integer iRef3 = 30;
List list = new Vector();
list.add(iRef1);
list.add(iRef2);
list.add(iRef3);
Collections.sort(list);//Natural sorting order
System.out.println("Natural sorting order...");
System.out.println(list.toString());
//[10, 20, 30]

//(1)

Collections.sort(list, new IntegerDescendingOrder());//Descending order


System.out.println("Descending order...");
System.out.println(list.toString());
//[30, 20, 10]
}
}
Collections.sort(List)
If we are not passing comparator object, by default, compareTo() method from Comparable interface will be
executed automatically which is meant for default natural sorting order (ascending order).

10

Collections.sort(List, Comparator)
If we are passing comparator object as an argument, then our own compare() method from Comparator
interface will be executed. Which is meant for customized sorting order (descending order).
If we implement compare() method in the following way then the corresponding outputs are:
public int compare(Object Obj1, Object Obj2){
Integer I1=(Integer) Obj1;
Integer I2=(Integer) Obj2;
Case1:
Return I1.CompareTo(I2); natural sorting order (ascending order) [10,20,30]
Case2:
Return - I1.CompareTo(I2); reserve of natural sorting order (descending order) [30,20,10]
Case3:
Return I2.CompareTo(I1); reserve of natural sorting order (descending order) [30,20,10]
Case4:
Return -1; just insertion order [20, 10, 30]
Case 5:
Return 0; just insertion order [20, 10, 30]
Case6:
Return 1; reverse of insertion order [30, 10, 20]

Case 4: Sort heterogeneous elements using Comparator interface.


Write a program, to insert string and stringbuffer objects into the Vector, where the sort order is increasing
string length order. If two string are having the same length then use the alphabetical order.
class LengthComparator implements Comparator{
public int compare(Object Obj1, Object Obj2){
String s1=Obj1.toString();
String s2=Obj2.toString();
int l1=s1.length();
int l2=s2.length();
if(l1>l2)
return +1;
else if (l1<l2)
return -1;
else
return s1.compareTo(s2);
}
}
//Client code.
import java.util.*;
11

class ComparatorDemo5{
public static void main(String[] args) {
List t=new Vector();
t.add(new StringBuffer("ABC"));
t.add(new StringBuffer("AA"));
t.add("XX");
t.add("ABCD");
t.add("A");
Collections.sort(t, new LengthComparator());
System.out.println(t);//[A, AA, XX, ABC, ABCD]
}
}
Note:
a) For predefine comparable classes like String, default natural sorting order is already available. If we dont
want, we can define our own Sorting order by using Comparator.
b) For predefine non-comparable classes like StringBuffer, default sorting order is not available. To define the
sorting order compulsory we should go for Comparator.
c) For our user defined classes like Student, we can define natural sorting order by implementing Comparable
Interface.
d) If we are not satisfy with default natural sorting order then we can implements our own customized sorting
order by using Comparator.
Comparison between Comparable and Comparator
Comparable
Comparator
Present in java.lang package
Present in java.util package
Contains only one method
Contains two methods
compareTo();
Compare(), and equals();
This interface is for defining natural sorting
This is for Customized sorting order.
order.
By default, some of the built-in classes are
Built-in classes never inherited from
inherited from Comparable interface.
Comparator interface.
It is a marker interface
Not a marker interface.

12