有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Lambda表达式在一个接口上工作吗?

爪哇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());
    }
});

爪哇8

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

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

如果接口Comparator有2个方法,而不是只有一个compare,那么可以使用Lambda吗

比如说

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

共 (2) 个答案

  1. # 1 楼答案

    功能接口只需要一种抽象方法,而你的接口却不需要这种方法。但是,您可以为其中一个方法提供默认实现。在这种情况下,它会起作用:

    @FunctionalInterface
    public interface Comparator<T> {
    
        int compare(T o1, T o2);
    
        default int reverseCompare(T o1, T o2) {
            return compare(o2, o1);
        }
    }
    
  2. # 2 楼答案

    lambda可用于预期实现功能接口的地方。功能接口的定义见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.

    所以在你的例子中,不,如果在ComparatorcomparecompareTest)上有两个抽象方法,你不能用lambda实现它

    例如,这是有效的:

    @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);
            }
        }
    }
    

    。。。但是如果我们加上^{

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

    。。。它将不再编译,因为它不再是一个功能接口。(如果我们删除注释,接口会编译(当然),但我们通过lambda使用它不会。)

    请注意,我们可以向^{添加一个默认方法:

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

    这没关系,因为界面上只有一个抽象方法