詳解Java函式式介面

啊道~發表於2020-12-23

知識點
函式式介面:有且只有一個抽象方法的介面,稱之為函式式介面
當然介面中可以包含其他的方法(預設,靜態,私有)

@FunctionalInterface註解
作用:可以檢測介面是否是一個函式式介面
是:編譯成功
否:編譯失敗(介面中沒有抽象方法抽象方法的個數多餘1個)

@FunctionalInterface
public interface MyFunctionalInterface {
    //定義一個抽象方法
    public abstract void  method();
}

函式式介面的使用:一般可以作為方法的引數和返回值型別

public class MyFunctionalInterfaceImpl implements MyFunctionalInterface {
    @Override
    public void method() {

    }
}

public class Demo {
    //定義一個方法,引數使用函式式介面MyFunctionalInterface
    public static void show(MyFunctionalInterface myInter){
        myInter.method();
    }

    public static void main(String[] args) {
        //呼叫show方法,方法的引數是一個介面,所以可以傳遞介面的實現類物件
        show(new MyFunctionalInterface() {
            @Override
            public void method() {

            }
        });

        show(new MyFunctionalInterfaceImpl());


        //呼叫show方法,方法的引數是一個函式式介面,所以我們可以Lambda表示式
        show(()->{
            System.out.println("使用Lambda表示式重寫介面中的抽象方法");
        });
        //簡化Lamba表示式
        show(()-> System.out.println("使用Lambda表示式重寫介面中的抽象方法"));

    }
}

如果一個方法的返回值型別是一個函式式介面,那麼就可以直接返回一個Lambda表示式。
當需要通過一個方法來獲取一個java.util.Comparator介面型別的物件作為排序器時,就可以調該方法獲取。

public class Comparator {
    //定義一個方法,方法的返回值型別使用函式式介面Comparator
    public static java.util.Comparator<String> getComparator(){
        //方法的返回值型別是一個介面,那麼我們可以返回這個介面的匿名內部類

        //一
       /* return new java.util.Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return 02-01;
            }
        };
        */

        //二
        return ((o1, o2) -> o2.length()-o1.length());



    }
}

例如java.lang.Runnable介面就是一個函式式介面,
假設有一個startThread方法使用該介面作為引數,那麼就可以使用Lambda進行傳參。
這種情況其實和Thread類的構造方法引數為Runnable沒有本質區別。

public class Runnable {
    //定義一個方法startThread,方法的引數使用函式式介面Runnable
    public static void startThread(java.lang.Runnable run) {
        //開啟多執行緒
        new Thread(run).start();
    }

    public static void main(String[] args) {
        //呼叫startThread方法,方法的引數是一個介面,那麼我們可以傳遞這個介面的匿名內部類
        startThread(new java.lang.Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "-->" + "執行緒啟動了");
            }
        });

        //呼叫startThread方法,方法的引數是一個函式式介面,所以可以傳遞Lambda表示式
        startThread(() ->
                System.out.println(Thread.currentThread().getName() + "-->" + "執行緒開啟"));


        //優化Lambda表示式
        startThread(()-> System.out.println(Thread.currentThread().getName()));
    }
}

相關文章