views:

143

answers:

4

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.

A: 

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.

Peter Štibraný
you did not understand the question. I want a direct as well, not just the reverse. The double reverse could be the normal
KARASZI István
@István: For natural ordering implement simple NaturalComparator for Comparable objects. I cannot find one in standard libraries.
Peter Štibraný
@Peter: it was in the OP, as you could see
KARASZI István
@István: yes I know, unfortunately I'm afraid that there isn't better answer than that :-(
Peter Štibraný
+4  A: 

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.

Joachim Sauer
It's my method so it does not have a natural order. (actually it has, because I wrote it to work, but I didn't want to, I'm looking for a nicer solution)
KARASZI István
And yes, I wrote it because I looked the source of `HashTree`.
KARASZI István
@KARASZI: which `HashTree` are you talking about? There's no such class in Java SE. Did you mean `TreeMap`?
Joachim Sauer
sorry, yes I meant `TreeMap`! :)
KARASZI István
`Ordering.natural()` is actually a nice starting point when composing Comparators using `Functions` (`Ordering.onResultOf(..)`), because usually every comparision boiles down to comparing `Strings`, `Numbers`, ... which all implement `Comparable`.
Willi
A: 

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]"
polygenelubricants
as you could see in the OP, that's what I did!
KARASZI István
A: 

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 :-).

Stephen C
And they accepting a `null` in every method where a `Comparator` was needed (and they pasted the `compareTo` method instead of creating a new `NaturalComparator` instead), so not really a **DRY** solution. me thinks...
KARASZI István