1

Below is the java program that uses lambda expression as parameter for sort() method.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Dummy {

    public static void main(String[] args) {
        List<String> a1 = new ArrayList<String>();
        a1.add("Zara");
        a1.add("Mahnaz");
        a1.add("Ayan");
        Collections.sort(a1,
                            (p1, p2) -> p1.compareTo(p2)

                        );

        System.out.println(a1.toString());
    } //end main

}

Using Eclipse, When I say F3 on sort() method, control is again actually going to same sort() method signature(definiton) used in java 7 version.

@SuppressWarnings({"unchecked", "rawtypes"})
    public static <T> void sort(List<T> list, Comparator<? super T> c) {
        //whatever
    }

In my code, Does the syntax of second parameter in sort() method is actually equivalent to implementing interface Comparator<T>, under the hood? something like

class ComparePersonsbyName implements Comparator<String>{
    public int compareTo(String p1, String p2){
        return p1.compareTo(p2);        
    }
}
Collections.sort(a1, new ComparePersonsbyName());
overexchange
  • 15,768
  • 30
  • 152
  • 347
  • @SkinnyJ Can I say, `Collections.sort(a1, (p1, p2) -> p1.compareTo(p2));` executes quick sort algo(current algo) on parallel core? because lambda expression syntax enabled this parallelism – overexchange Jun 29 '15 at 07:52
  • 1
    You are not seeing the same definition as in Java 7. The Java 8 implementation you have posted, delegates to [`List.sort`](http://docs.oracle.com/javase/8/docs/api/java/util/List.html#sort-java.util.Comparator-) which doesn’t exist in Java 7. Nevertheless, this implementation detail has nothing to do with lambdas. – Holger Jun 29 '15 at 08:12
  • @Holger In jdk 1.6 code `../java/util/Collections.java`, I see the same defi of `sort()` without annotation. – overexchange Jun 29 '15 at 08:17
  • BTW, In functional languages, lambda expressions are used as first class objects. Here in java 8, they lambda expressions can only be passed as argument but cannot return. – overexchange Jun 29 '15 at 08:22
  • 1
    If you see *this implementation*, you are looking at the Java 8 implementation. Are you sure that you understand what you IDE does? Changing the compiler-compliance level does not necessarily change the JRE you are using. You must have a Java 6 JDK installed to be able to see the source code of the JRE6. – Holger Jun 29 '15 at 08:23
  • 1
    Of course, you can return a lambda expression. It works the same way as it works when passing it as an argument, the return type must be a functional interface. – Holger Jun 29 '15 at 08:24
  • @Holger rt.jar has source attachment as jdk 8 in the InstalledJRE setting of eclipse. – overexchange Jun 29 '15 at 08:25
  • 1
    Right, no one questioned that you see *the Java 8 source code*. What you don’t see is the Java 7 source code. [Here](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/Collections.java#Collections.sort%28java.util.List%2Cjava.util.Comparator%29) you can see how it looks like in Java 7. – Holger Jun 29 '15 at 08:27
  • yes the signature of the `sort` method is same. – overexchange Jun 29 '15 at 08:29
  • @overexchange: no, lambda expressions are not limited to being arguments, they are regular values with the only restriction that the "target type" must be a functional interface. In a method returning Runnable you can certainly return `() -> System.out.print("hello")` – Stephan Herrmann Jun 29 '15 at 20:43
  • While generally it;s a good intuition to think of a lambda as syntactic sugar for an anonymous class instantiation, there's a subtle technical difference: lambdas don't require the instantiation of a new object per usage, i.e., lambda expressions are subject to some optimization that's not available for the old style, see also http://stackoverflow.com/questions/16827262/how-will-java-lambda-functions-be-compiled – Stephan Herrmann Jun 29 '15 at 20:54

1 Answers1

4

Yes, Comparator is a functional interface

Yosef Weiner
  • 5,432
  • 1
  • 24
  • 37
  • Does functional interface is an interface that has only one function prototype? or Does functional interface can have more than one function protoype? – overexchange Jun 29 '15 at 06:46
  • 1
    @overexchange fixed the link in the answer. To quote from the linked page: "Each functional interface has a single abstract method, called thefunctional method for that functional interface, to which the lambda expression's parameter and return types are matched or adapted." – Yosef Weiner Jun 29 '15 at 06:50
  • 1
    `int compare(T o1, T o2)` is the functional method – Yosef Weiner Jun 29 '15 at 06:59
  • yes, I understand that. If you design one, it is possible that an interface can have more than one functional methods. – overexchange Jun 29 '15 at 07:01
  • 1
    No. [This article](http://www.lambdafaq.org/what-is-a-functional-interface/) explains it well: "The interface Comparator is functional because although it declares two abstract methods, one of these—equals— has a signature corresponding to a public method in Object. Interfaces always declare abstract methods corresponding to the public methods of Object, but they usually do so implicitly. Whether implicitly or explicitly declared, such methods are excluded from the count." – Yosef Weiner Jun 29 '15 at 07:05
  • 1))) Excluding public methods of `class Object`, if you design an interface, Can't there be more than one functional methods? 2))) If annotation type `@FunctionalInterface` is not tagged before `public interface ActionListener extends EventListener{}` How does `javac` know that `ActionListener` is a functional interface? – overexchange Jun 29 '15 at 07:37
  • 1
    Please read the linked articles. 1. No. "Each functional interface has a single abstract method, called the functional method for that functional interface". 2. No. "The interfaces in this package are annotated with FunctionalInterface. This annotation is not a requirement for the compiler to recognize an interface as a functional interface, but merely an aid to capture design intent and enlist the help of the compiler in identifying accidental violations of design intent." – Yosef Weiner Jun 29 '15 at 07:45