سؤال

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]"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top