简体   繁体   中英

does Lambda expression work on one interface?

Java 7

List<Person> personList = Person.createShortList();

// Sort with Inner Class
Collections.sort(personList, new Comparator<Person>() {
    public int compare(Person p1, Person p2) {
        return p1.getSurName().compareTo(p2.getSurName());
    }
});

Java 8

Collections.sort(personList, (Person p1, Person p2) -> 
                 p1.getSurName().compareTo(p2.getSurName()));

for (Person p : personList) {
    p.printName();
}

If the interface Comparator has 2 methods and not just one compare is it possible to use Lambda ?

for example

public interface Comparator<T> {
    int compare(T o1, T o2);
    int compareTest(T o1, T o2);
}

Functional interfaces need exactly one abstract method which is not the case for your interface. However you could provide a default implementation for one of the methods. In that case it would work:

@FunctionalInterface
public interface Comparator<T> {

    int compare(T o1, T o2);

    default int reverseCompare(T o1, T o2) {
        return compare(o2, o1);
    }
}

Lambdas can be used where implementations of functional interfaces are expected. The definition of a functional interface is in JLS§9.8 :

A functional interface is an interface that has just one abstract method (aside from the methods of Object ), and thus represents a single function contract. This "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.

So in your example, no, if there were two abstract methods on Comparator ( compare and compareTest ), you couldn't implement it using a lambda.

For example, this works:

@FunctionalInterface
interface Foo {
    void method1(int x);
}

public class Example {
    public static final void main(String[] args) {
        new Example().testFoo(x -> {
            System.out.println(x);
        });
    }

    private void testFoo(Foo f) {
        for (int x = 0; x < 5; ++x) {
            f.method1(x);
        }
    }
}

...but if we add to Foo :

// WON'T COMPILE
@FunctionalInterface
interface Foo {
    void method1(int x);
    void method2(int x);
}

...it won't compile anymore because it's no longer a functional interface. (If we removed the annotation, the interface would compile [of course], but our use of it via a lambda wouldn't.)

Note that we could add a default method to Foo :

@FunctionalInterface
interface Foo {
    void method1(int x);
    default void method2(int x) {
        // ...
    }
}

That's okay because there's only one abstract method on the interface.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM