Comparable vs. Comparator
Classes should implement the Comparable interface to control their natural ordering.
Objects that implement Comparable can be sorted by
Collections.sort()
and Arrays.sort()
and can be used as keys in a sorted map or elements in a sorted set without the need to specify a Comparator.« Interface » Comparable |
+ compareTo(Object) : int |
compareTo()
compares this object with another object and returns a negative integer, zero, or a positiveinteger as this object is less than, equal to, or greater than the other object.Use Comparator to sort objects in an order other than their natural ordering.« Interface » Comparator |
+ compare(Object, Object) : int + equals(Object) : boolean |
compare()
compares its two arguments for order, and returns a negative integer, zero, or a positiveinteger as the first argument is less than, equal to, or greater than the second.Examples:
1) Comparable
public class Book implements Comparable { String title; int isbn; Book(String title, int isbn) { this.title = title; this.isbn = isbn; } public String toString() { return title + " " + String.valueOf(isbn); } public boolean equals(Object object) { if (object instanceof Book) { Book other = (Book) object; return this.title.equals(other.title) && (this.isbn == other.isbn); } else { return false; } } public int compareTo(Object object) { Book other = (Book) object; if (this.title.equals(other.title)) { return this.isbn - other.isbn; } return this.title.compareTo(other.title); } }
2)
import java.util.*; public class TestCollections { static List list = new LinkedList(); public static void main(String[] args) { list.add(new Book("Patterns", 12345)); list.add(new Book("Patterns", 34567)); list.add(new Book("Examples", 23456)); testContains(); testISBNSort(); try { testNaturalSort(); } catch (Throwable t) { System.out.println(t); } } static void testContains() { System.out.println("\nTESTING CONTAINS"); // this is what we're looking for Book patterns = new Book("Patterns", 12345); // do we have it? System.out.println("We have it: " + list.contains(patterns)); } static void testISBNSort() { System.out.println("\nTESTING ISBN SORT"); // sort using a comparator Collections.sort(list, new Comparator() { public int compare(Object object1, Object object2) { Book book1 = (Book) object1; Book book2 = (Book) object2; return book1.isbn - book2.isbn; } }); // print the collection Iterator i = list.iterator(); while (i.hasNext()) { System.out.println(i.next()); } } static void testNaturalSort() { System.out.println("\nTESTING NATURAL SORT"); // sort if we're comparable Collections.sort(list); // print the collection Iterator i = list.iterator(); while (i.hasNext()) { System.out.println(i.next()); } } }
==============================================================================
Use of comparable and comparator interface
In java the element in collections can be sorted by using TreeSet or TreeMap. To sort the data elements a class needs to implement Comparator or Comparable interface. Thats why all Wrapper classes like Integer,Double and String class implements Comparable interface.A class implementing Comparable interface need to override compareTo(Object obj) method and put the logic for sorting.
1234
The method returns an
int
value :-
1
,
0
,
1
It will
return
-
1
: If
this
object is lesser than the passed object
It will
return
0
: If
this
object is same the passed object
It will
return
1
: If
this
object is greater than the passed object
Consider a class Person.
12345678910111213141516171819202122232425262728293031
class
Person {
public
String name;
public
String lastName;
public
Person(String name, String lastName){
this
.name=name;
this
.lastName=lastName;
}
public
String getName(){
return
name;
}
public
String getLastName(){
return
lastName;
}
public
static
void
main(String arg[]){
List<person> myList =
new
ArrayList<person>();
myList.add(
new
Person(
"Robert"
,
"USA"
));
myList.add(
new
Person(
"Andy"
,
"UK"
));
myList.add(
new
Person(
"Harish"
,
"India"
));
for
(Person person : myList){
System.out.println(
"My name is "
+person.getName());
}
}
}
Output is :
My name is Robert
My name is Andy
My name is Harish
</person></person>
But now i want that the objects to be sorted on name basis should be retrieved in sorted order. Consider a class Person.
123456789101112131415161718192021222324252627282930313233343536
class
Person
implements
Comparable{
public
String name;
public
String lastName;
public
Person(String name, String lastName){
this
.name=name;
this
.lastName=lastName;
}
public
String getName(){
return
name;
}
public
String getLastName(){
return
lastName;
}
public
int
compareTo(Object obj){
Person p = (Person)obj;
return
this
.name.compareTo(p.getName);
}
public
static
void
main(String arg[]){
List<person> myList =
new
ArrayList<person>();
myList.add(
new
Person(
"Robert"
,
"USA"
));
myList.add(
new
Person(
"Andy"
,
"UK"
));
myList.add(
new
Person(
"Harish"
,
"India"
));
Collections.sort(myList);
for
(Person person : myList){
System.out.println(
"My name is "
+person.getName());
}
}
}
Output is :
My name is Andy
My name is Harish
My name is Robert
</person></person>
Couple of things which needs to be taken in consideration: 1) Collections.sort() will sort only the collection having objects which implements either one of the comparing interface. 2) Collections.sort() will sort the same list.Comparator interface is used when an extra logic is required to sort the objects. One need to override compare(Object obj1, Object obj2) method.For example you want the list of Person object to be sorted on the basis of complete name i.e "name lastName" but also on the other hand doesnt want to change the Person class default sorting implementation or Person class is a jar so so no code modification in it can be done. First create a Custom Comparator.
123456789101112131415161718192021222324252627
public
class
MyCustomComparator
implements
Comparator{
public
int
compare(Object obj1, Object obj2){
Person p1 =(Person) obj1;
Person p2 =(Person) ob2;
String p1Name = p1.getName()+
" "
+p1.getLastName();
String p2Name = p2.getName()+
" "
+p2.getLastName();
return
p1Name.toCompareTo(p2Name);
}
}
// Changes made in main method of Person class.
public
static
void
main(String arg[]){
List<person> myList =
new
ArrayList<person>();
myList.add(
new
Person(
"Robert"
,
"USA"
));
myList.add(
new
Person(
"Robert"
,
"UK"
));
myList.add(
new
Person(
"Robert"
,
"India"
));
Collections.sort(myList
new
MyCustomComparator());
for
(Person person : myList){
System.out.println(
"My name is "
+person.getName() +
" "
+ person.getLastName());
}
}
OutPut:
My name is Robert India
My name is Robert UK
My name is Robert USA
</person></person>
Couple of things which needs to be taken in consideration: 1) For Comparator interface you need to override method compare(obj) 2) In collections.sort() the instance of Comparator need to be passed. In this example the list is sorted according to the custom Comparator created
Comments