java.util.Comparator
is used to define a special sort order for a class.
- Use the ComparatorCutter
to mindlessly crank out complete code for Comparables
and Comparators. The code will help teach you the
structure so that you can write them without such training wheels.
- How do you remember that java.util.
Comparable. compareTo
defines a natural order where java.util. Comparator.
compare defines an auxiliary order? I think about it
this way:
“Does it makes sense to compare
two Oranges? If so they are Comparable.
I will need a method that compares this Orange
Object to (compareTo)
another. If I want do define an alternate order, I need to invent some sort of
independent machine, a Comparator to do it.
The comparison is not inherent to Oranges, so there
is no this. Instead, I compare
two Orange Objects.”
To implement java.util.Comparator you must write
two methods. It typically describes a small delegate object passed to a sort to
describe some special sort order. The compare method
compares two objects of the class you want to sort. The equals
method compares this java.util.Comparator to
another to see if they represent the same order. It does not compare two
objects of the class you want to sort. Normally you also redefine equals
when you implement Comparator even though it is
not part of the Comparator interface. There are
no generics involved in overriding equals.
public final int compare( Object o1, Object o2 );
public boolean equals( Object obj );
Here is a typical java.util.Comparator.compare routine:
If you are using a java.util.Comparator only once,
you might implement it as an anonymous inner class like this:
Here is a very general purpose Comparator for
sorting rows of a Table (array of arrays or Vector of arrays) where each element
is some sort of Object that implements Comparable.
Tips
- If you make your Comparators nested static
classes of the class they sort, they will be easy to find and easy to associate
with the correct class.
- String.CASE_INSENSITIVE_ORDER
is a Comparator you can use without writing any
code. Unfortunately there is no String.CASE_SENSITIVE_ORDER.
The reason is String’s Comparable
implementation provides it naturally without a Comparator.
You can use the following code to sort by natural Comparable
order when a Comparator is required.
- Beware of using subtraction in writing Comparators
rather than < > and Double.
compareTo if there is any possibility you will be
using numbers large enough to overflow and give the wrong sign comparing them
with subtraction. The other problem with subtraction is it might give a long
or double result which is not an integer value
suitable for return.
Descending/Inverse/Reverse Order with
reverseOrder
Sorting ascending order means sorting with the small
elements first then the big. This is usual ordering. Descending
order means sorting with the big elements first then the small.
If you have a Comparator
or Comparable of some kind, you can convert it into
one that sorts into the reverse of the usual order, e. g. if the original sorts
alphabetically, the new one will sort in reverse alphabetical order. Here is how
you use it:
If you don’t have a suitable base Comparator,
just write an ordinary Comparator from scratch and
reverse the operands to each compare inside it, or return -
result instead of result.
Comparator Using Generics
You don’t need any casts since the compiler checks that no non-Pair
classes ever get inside the ArrayList<Pair>.
Learning More
Sun’s Javadoc on
Comparable class : available:
Note java.lang.Comparable
but java. util.Comparator.
Sun’s Javadoc on
Comparator class : available:
Sun’s Javadoc on
Collections.reverseOrder() : available:
Sun’s Javadoc on
Collections.reverseOrder(Comparator) : available:
Sun’s Javadoc on
String.CASE_INSENSITIVE_ORDER : available: