Direct comparator in Java out of the box
I have a method which needs a Comparator
for one of its parameters. I would like to pass a Comparator
which does a normal comparison and a reverse comparator which does in reverse.
java.util.Collections
provides a reverseOrder()
this is good for the reverse comparison, but I could not 开发者_开发百科find any normal Comparator
.
The only solution what came into my mind is Collections.reverseOrder(Collections.reverseOrder())
. but I don't like it because the double method calling inside.
Of course I could write a NormalComparator
like this:
public class NormalComparator<T extends Comparable> implements Comparator<T> {
public int compare(T o1, T o2) {
return o1.compareTo(o2);
}
}
But I'm really surprised that Java doesn't have a solution for this out of the box.
Most places where you can specify a Comparator
also have a version without using a Comparator
at all in which case it uses the natural order (i.e. it expects all objects to implement Comparable
and uses compareTo
).
So the usualy solution to this is to not specify a Comparator
at all. Do you have a specific case where only the Comparator
approach is supported?
If you absolutely need it, the Google Collections (as well as Guava, which is a superset of the Google Collections) provides Ordering.natural()
which returns a Ordering
object that represent the natural order as defined by the Comparable
interface. Ordering
implements Comparator
, so you can simply use that.
But I'm really surprised that Java doesn't have a solution for this out of the box.
I suppose it would be useful in a few cases ... like yours. But in most use-cases an application would simply use the object's compareTo
method directly. Indirecting via an Comparator
object would serve no purpose ... most of the time.
My guess is that the designers of those Java APIs did not consider your use-case important enough to support directly. Besides, your implementation is only four lines of code.
The Java class libraries are not perfect. Learn to live with it :-).
For reverse ordering use Collections.reverseOrder()
...
Returns a comparator that imposes the reverse of the natural ordering on a collection of objects that implement the Comparable interface.
There is usually no need for a natural order Comparator<T>
, since usually there's an overload that takes a Comparable<T>
. You can always follow the example set by Collections.reverseOrder()
and write something like this:
private static final Comparator<?> NATURAL_ORDER =
new Comparator<Comparable<Object>>() {
@Override public int compare(Comparable<Object> o1, Comparable<Object> o2) {
return o1.compareTo(o2);
}
};
@SuppressWarnings("unchecked")
public static <T> Comparator<T> naturalOrder() {
return (Comparator<T>) NATURAL_ORDER;
}
You can then write something like:
List<String> names = Arrays.asList("Bob", "Alice", "Carol");
Collections.sort(names, naturalOrder());
System.out.println(names);
// prints "[Alice, Bob, Carol]"
精彩评论