【Java8】函數(shù)式接口及Lamda表達(dá)式詳解

函數(shù)式接口基本介紹

1、函數(shù)式接口:只有一個方法的接口;
2、有且僅有一個抽象方法的接口,但是可以有多個非抽象方法的接口。函數(shù)式接口可以被隱式轉(zhuǎn)換為 lambda 表達(dá)式。Lambda就是Java中函數(shù)式編程的體現(xiàn);
3、主要分布在 java.util.function 包下,常見的 4大原始函數(shù) 接口為:Function (函數(shù)型接口)、Predicate (斷定型接口)、Consumer (消費型接口)、Supplier (供給型接口)

使用場景

1、在函數(shù)式編程場景中進(jìn)行使用,Java中的函數(shù)式編程體現(xiàn)就是Lambda,所以函數(shù)式接口就是可以適用于Lambda使用的接口;
2、函數(shù)作為參數(shù),匿名內(nèi)部類替代,可以簡化代碼,提高編碼效率;
3、延遲加載,即滿足條件才會執(zhí)行,不滿足條件就不執(zhí)行。

@FunctionalInterface注解

1、 Java 8中專門為函數(shù)式接口引入了一個新的注解:@FunctionalInterface 。該注解放在接口上,表示此接口是一個函數(shù)式接口。并且提示編譯器去檢查接口是否僅包含一個抽象方法,即,是否符合函數(shù)式編程的定義;
2、 注意:如果自定義一個符合規(guī)范的函數(shù)式接口,也可以不加@FunctionalInterface注解,此注解只是起到一個提示編譯器進(jìn)行規(guī)范檢查的作用;
3、 日常開發(fā)中用的最多的函數(shù)式接口的,比如線程中的 Runnable

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

常見函數(shù)式接口使用

1、Function (函數(shù)型接口),有一個輸入?yún)?shù),有一個輸出,apply ()方法就是該接口的唯一方法,也就是繼承該Function接口,唯一需要實現(xiàn)的方法,代碼示例:

// 輸出輸入的參數(shù):有一個輸入?yún)?shù),和一個輸出
public static void main(String[] args) {
  // 1. 初始化,并且實現(xiàn)該接口的唯一實現(xiàn)方法
  Function<String,String> function = new Function<String, String>() {
    @Override
    public String apply(String param) {
        return param;
    }
  };
  System.out.println(function.apply("abc"));
}

Lambda就是Java中函數(shù)式編程的體現(xiàn) 也就是說只要是函數(shù)式接口,就可以使用lambda表達(dá)式來簡化代碼!如下:

public static void main(String[] args) {
     // 使用lambda表達(dá)式
     Function<String,String> function = (str)->{return str;};
     //或者我們可以更簡單點,把str的()括號去掉也是可以的
    // Function<String,String> function = str->{return str;};
     System.out.println(function.apply("abc"));
}

典型的lambda表達(dá)式語法:()->{};str是傳入的參數(shù)
2、Predicate (斷定型接口),有一個輸入?yún)?shù),返回值只能是布爾值,代碼示例:

Predicate<Integer> predicate = integer -> {
        if(integer > 0){
        return true;
        }
        return false;
        };
        predicate.test(3);

3、 Consumer (消費型接口),只有入?yún)?,沒有返回值

Consumer<String> consumer = str-> System.out.println(str);
consumer.accept("abc");

4、Supplier (供給型接口),沒有參數(shù),只有返回值

Supplier<Integer> supplier = ()-> 1024;
System.out.println(supplier.get());

Lambda表達(dá)式及匿名內(nèi)部類
1、Lambda表達(dá)式(閉包):java8的新特性,lambda運(yùn)行將函數(shù)作為一個方法的參數(shù),也就是函數(shù)作為參數(shù)傳遞到方法中。使用lambda表達(dá)式可以讓代碼更加簡潔;
2、lambda表達(dá)式,其實本質(zhì)來講,就是?個匿名函數(shù)。因此在寫lambda表達(dá)式的時候,不需要關(guān)心方法名是什么。實際上,我們在寫lambda表達(dá)式的時候,也不需要關(guān)心返回值類型;
3、Lambda使用代碼示例:

// 1、匿名內(nèi)部類沒有類名,只被使用一次,使代碼更簡潔;
// 2、在定義之后就可以立即使用,定義時就實例化
// 3、方便編寫事件驅(qū)動程序及線程代碼
public class LambdaUse {
    // 匿名內(nèi)部類
    public void anonymousInner(String hello){
        HelloFunction helloFunction = new HelloFunction(){
            @Override
            public void sayHello(String hello){
                System.out.println(hello);
            }
        };
        helloFunction.sayHello(hello);
    }
    // 局部類
    public void implementsClass(){
        class Hello implements HelloFunction{
            @Override
            public void sayHello(String hello) {
                System.out.println("擴(kuò)展類:"+hello);
            }
        }
        Hello hello = new Hello();
        hello.sayHello("匿名內(nèi)部類");
    }
    // lambda表達(dá)式
    public void lambda(String hello){
        HelloFunction helloFunction = System.out::println;
        helloFunction.sayHello(hello);
    }

    public static void main(String[] args) {
        LambdaUse lambdaUse = new LambdaUse();
        lambdaUse.lambda("你好匿名內(nèi)部類。");
        lambdaUse.implementsClass();
    }
    // 匿名內(nèi)部類:可以是接口,也可以是抽象類,還可以是具體類
    // Lambda表達(dá)式:只可能是接口,如果接口中僅有一個抽象方法,可以使用Lambda表達(dá)式,也可以使用匿名表達(dá)式,
    // 如果接口中有多個抽象,只能使用匿名內(nèi)部類
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容