4

Custom implementation of Comparator

@FunctionalInterface
public interface Comparator<T>  {

int compare(T t1, T t2);

static <T> Comparator<T> comparing(
        Function<T, Comparable> f){
    return (p1, p2) -> f.apply(p1).compareTo(f.apply(p2));
}

default Comparator<T> thenComparing(
        Comparator<T> cmp){
            return (p1, p2) ->
                    this.compare(p1, p2) == 0 ?
                            cmp.compare(p1, p2) : this.compare(p1, p2);
}

default Comparator<T> thenComparing(
        Function<T, Comparable> f){
            Comparator<T> cmp = comparing(f);
    return thenComparing(cmp);
  }
}

I have created a Person class with three fields, namely the firstName, lastName and age, and their respective getters and setters. Using the custom Comparator class I want to sort an array of persons in main as under:

    Comparator<Person> cmp = Comparator
            .comparing(Person::getLastName) // Extract Property and compare
            .thenComparing(Person::getFirstName)
            .thenComparing(Person::getAge);

     Person arr[] = new Person[]{
        new Person("Sean", "Gilmore", 22),
                new Person("Aaron", "Reidy", 21),
                new Person("Jane", "Kennedy", 53),
                new Person("Mike", "English", 49)
    };


    Arrays.sort(arr, cmp);

However Arrays.sort(arr, cmp); throws a compile error no instance of type variable T exists so that Comparator<Person> conforms to Comparator<? super T>

I'm thrown off by this error and I would like to know how to sort the Person array using cmp Comparator.

0

2 Answers 2

3

You can easily adapt your Comparator to the JDK's like this:

Arrays.sort(arr, cmp::compare);

I believe Guava recommended a similar pattern to adapt their functional interfaces before they were retrofitted for Java 8.

Sign up to request clarification or add additional context in comments.

7 Comments

@shmosei cmp:compare would still give you a java.util.Comparator. There are other options too but you eventually can't pass anything but a java.util.Comparator to the method in question so the answer still remains : you can't do it.
@CKing I didn't interpret the question as trying to avoid the JDK's Comparator entirely. I think OP is just asking how his custom interface can be used with the built-in sort functionality.
@shmosei I fell for the same argument in my head but then I read this line from the question I'm thrown off my this error and I would like to know how to sort the Person array using cmp Comparator which convinced me that the OP clearly needed an explanation for why it can't be done rather than how to do it. (The OP was thrown away that he can't pass a Comparator to a method that takes a Comparator). This can be further inferred from the comment on my answer from the OP saying So that means I'll have to implement sort to use my custom Comparator? The OP is exploring Java in general!
@CKing I hear you, but I suspect you're putting more thought into OP's words than he did :)
@CKing That's one statement I fully agree with.
|
3

The fully qualified name of a class in Java includes it's package name.

The Arrays.sort method expects a java.util.Comparator implementation. Your custom Comparator is not the same is java.util.Comparator.

The sort method in Arrays class is a static method so you can't extend Arrays and override this method. If you want to use Arrays.sort, use an implementation of java.util.Comparator. There is no way around it.

6 Comments

So that means I'll have to implement sort to use my custom Comparator?
@HarpreetSingh Or you write a facade for your custom Comparator class. Anyway, why don't you use the genuine Comparator?
@Flown That Facade is still a java.util.Comparator.
@CKing This is what I've meant.
Why are you reinventing wheels?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.