This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
You should implement Comparable if there is a logical ordering on your class. Strings, integers, dates, they all have a logical ordering.
If you can't think of a logical ordering (like Class), the objects of the class you want to sort do not implement Comparable (like URL), or you want a different sort order (like reversed, or on another field), you should use a Comparator.
Basically a Comparator can be used to compare objects other than by their natural ordering, if any.
Natural order is an obvious order, so if you have objects that are numbers, you usually define the natural order so larger numbers are greater than smaller ones. If you have a list of names, one usually has a natural order of alphabetic.
Names/Strings can get a bit tricky with multi-lingual support, as languages often have special case rules for ordering. For example, in Spanish, the "ch" is treated as a single letter that sorts after 'c' and before 'd'
if you have an object for a person, you can pick the 'natural order' which really means that there is no obvious natural order. You could order by age, or height, or weight, or occupation.
let's say you have 5 people in a company. A,B,C,D and E with their own employee numbers.
If you want to order them, the best and default way is to order them based on the alphabets on their names. - This is natural ordering. You dont need to do anything for the comparison to be done and the resultant ordering. - This is what a Comparable does!
Whereas for some project specific purpose you would like to order them based on their employee numbers. This is one way. Moreover, you can even consider them based on their seniority as some people with more experience might have joined later. - This way you have YOUR OWN way of ordering and NOT the default/natural ordering. - This is what a Comparator does.
For a comparator, you need to provide your own way of ordering!
That's close but leaves a few gaps. There's no free lunch with custom classes.
If you write a class Person and make it implement Comparable, there is still work to do. You have to implement the compareTo method, which will compare "this" Person to another. When you write compareTo you can choose to compare first names, last names, employee ids, shoe sizes, etc. Once you write compareTo, you can put Person objects in a sorted collection like TreeSet.
If you write a class Person but do NOT make it implement Comparable, you won't be able to put it into a TreeSet by itself. You'll need a Comparator to do the work that Person doesn't do. A Comparator compares two objects, but neither one is itself. Again, it can compare on name, employee id, age, etc.
Sometimes you'll implement Comparable for the most common sort order. Maybe you choose last name + first name. Then one day you want them sorted by employee id. Now you can write a Comparator that does the employee id comparison.
Does most of that make sense?
Think about a Person class with two Strings for first name and last name. Could you write a compareTo method to sort on last name and first name? Try to make something like this run:
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi