一起來學(xué)Java8(一)——函數(shù)式編程

在這篇文章中,我們將了解到在Java8下如何進(jìn)行函數(shù)式編程。

函數(shù)式編程

所謂的函數(shù)式編程就是把函數(shù)名字當(dāng)做值進(jìn)行傳遞,然后接收方拿到這個函數(shù)名進(jìn)行調(diào)用。

首先來看下JavaScript如何進(jìn)行函數(shù)調(diào)用

var Person = {
    sayHello: function(name) {
        alert('hello ' + name);
    }
};

function work(fn) {
    fn('Jim');
}

work(Person.sayHello); // hello Jim

在這個例子中,sayHello函數(shù)被當(dāng)做一個參數(shù)傳遞到另一個work函數(shù)當(dāng)中,然后work調(diào)用給定的函數(shù)。

Java8中的函數(shù)式編程

在Java中,充當(dāng)函數(shù)的角色是類中方法,在本篇文章當(dāng)中提到的函數(shù)泛指方法。

接下來看下Java8中一個簡單的函數(shù)式編程例子:

import java.util.function.Consumer;

class Person {
    public static void sayHello(String name) {
        System.out.println("hello " + name);
    }
}

public class TestPerson {

    public static void main(String[] args) {
        work(Person::sayHello); // hello Jim
    }
    
    public static void work(Consumer<String> consumer) {
        consumer.accept("Jim");
    }
}

從這個例子中可以看到,Java8傳遞函數(shù)的方式跟JavaScript不一樣,在Java8當(dāng)中傳遞函數(shù)的方式是:方法引用::方法名稱,如:String.valueOf,String.toString。接收參數(shù)Consumer可以先不用去了解,后面會講到。

為了接收傳遞過來的函數(shù)引用,Java設(shè)計者提出了一個函數(shù)式接口的概念

函數(shù)式接口
函數(shù)式接口定義:一個接口里面只有一個抽象方法。

如下面幾個接口都是函數(shù)式接口:

? Consumer
? Supplier
? Runnable
? Callable
查看Runnable類的源碼可以發(fā)現(xiàn),在類上方定義了一個@FunctionalInterface注解

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

? @FunctionalInterface注解的作用:
當(dāng)做一個標(biāo)記使用,標(biāo)記當(dāng)前接口是一個函數(shù)式接口,如果你的接口有多個抽象方法或沒有抽象方法,那么會編譯報錯。它的作用有點類似于@override注解,有輔助作用,但不是必須的。如果你想設(shè)計一個函數(shù)式接口,那么最好把它加上。

// 編譯不通過,必須要有一個抽象方法
@FunctionalInterface
public interface InterfaceA {
    
}

// 編譯通過,只有一個抽象方法
@FunctionalInterface
public interface InterfaceB {
    void run();
}

// 編譯不通過,只能有一個抽象方法
@FunctionalInterface
public interface InterfaceC {
    void run();
    
    void run2();
}

// 編譯通過,run2是默認(rèn)方法,并不是抽象方法
// 在這里只有一個run抽象方法
@FunctionalInterface
public interface InterfaceD {
    void run();
    
    default void run2() {};
}

在例子InterfaceD中涉及到了接口默認(rèn)方法default void run2() {};,這里略過不講,后續(xù)文章中會有提到。

我們可以實現(xiàn)一個自定義的函數(shù)式接口,替代Consumer

// 自定義函數(shù)式接口
@FunctionalInterface
public interface FunctionCaller<T> {
    void call(T t);
}

public class TestPerson2 {

    public static void main(String[] args) {
        work(Person::sayHello);
    }
    
    public static void work(FunctionCaller<String> caller) {
        caller.call("Jim");
    }
}

小結(jié)

本篇主要講解了在Java8下如何進(jìn)行函數(shù)式編程,以及如何定義和使用一個函數(shù)式接口。

https://shimo.im/docs/gGQHg8xPC3X8cPHV/ 《2020年最新Java架構(gòu)師系統(tǒng)進(jìn)階資料免費領(lǐng)取》,可復(fù)制鏈接后用石墨文檔 App 或小程序打開

?著作權(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)容