7

The definition of a functional Interface in Java 8 says:

A functional interface is defined as any interface that has exactly one explicitly declared abstract method. (The qualification is necessary because an interface may have non-abstract default methods.) This is why functional interfaces used to be called Single Abstract Method (SAM) interfaces, a term that is still sometimes seen.

So how come we have this:

List<Double> temperature = 
   new ArrayList<Double>(Arrays.asList(new Double[] { 20.0, 22.0, 22.5 }));
temperature.sort((a, b) -> a > b ? -1 : 1);

As the sort method in List is:

default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

And the lambda expression says:

Lambda Expression should be assignable to a Functional Interface

The Comparator interface has two abstract methods which are compare and equals and is annotated with @FunctionalInterface. Does not this violate the definition of a functional interface having only one abstract method?

4
  • 1
    Every class in Java inherits from Object and has the implicit methods Object::toString, Object::equals, Object::hashCode. Therefore Comparator<T> is an interface with a SAM which overrides the implicit method. Commented Apr 25, 2016 at 15:13
  • Where did you get that definition? Commented Apr 25, 2016 at 15:21
  • There are a lot of blogs where I read the definition which I shared above. And as per the guidelines of stackoverflow I cannot share the link to other blogs.. Commented Apr 25, 2016 at 15:34
  • 2
    Don’t base your knowledge on Blogs. There is enough official material to study. You may use 3rd party tutorials and blogs, but if they cause confusion, verify with the official sources. Commented Apr 25, 2016 at 17:25

1 Answer 1

14

It is true that the Comparator interface has 2 abstract methods. But one of them is equals, which overrides the equals method defined in the Object class, and this method doesn't count.

From @FunctionalInterface:

If an interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface's abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere.

As such, this makes the Comparator interface a functional interface where the functional method is compare(o1, o2).

The lambda expression (a, b) -> a > b ? -1 : 1 complies with that contract: it declares 2 parameters and return an int.

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

3 Comments

And if we are at it, it should be emphasized that this definition, unlike claimed in the question’s quote, does not require the abstract method to be declared explicitly.
And it should be mentioned that, while this lambda expression complies with the shape of the function and hence is accepted by the compiler, it is violating the contract of the Comparator interface and can cause an arbitrary mess at runtime…
Yes, in this case Comparator.reverseOrder() would be a better choice.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.