天天看點

函數式程式設計【1】——初識函數式程式設計

1.一段話了解函數式程式設計

首先說一下

函數

方法

的差別,簡單的可以了解為同一個東西,都是一個執行塊。前者是

面向過程

的叫法,後者是

面向對象

的叫法。是以說函數式程式設計某種程度上來說也可以了解為方法程式設計。而寫過js的同學應該知道,在js中的函數是允許把另外一個函數作為自身參數的。後來仔細看了《java8實戰》,談一下自己的了解。函數式程式設計這個概念就是讓我們用一種新的思維方式去寫java。

2.舉個栗子

我們先定義一個簡單的

People

接口。

public interface People {
    void say();
}
           

然後定義一個

ZhangSan

類,當我們需要建立

People

執行個體的時候,顯然需要去實作這個接口裡的方法。

public class ZhangSan {
    
    People zhangsan = new People() {
        @Override
        public void say() {
               System.out.println("i am zhangsan");
        }
    };
}
           

同樣的,建立一個LiSi類,也需要這麼操作。

public class LiSi {
    
    People liSi = new People() {
        @Override
        public void say() {
            System.out.println("i am lisi");      
        }
    };
}
           

發現問題了嗎?每次建立接口對象的時候,“=”右邊的格式是固定的。再者我們建立接口的目的是什麼?是為了使用他的方法。那麼可以直接使用他的方法而不建立執行個體嗎?java8是這麼做的。把上面代碼重複的部分改為:

() ->

是以上面的代碼也可以寫成

public class LiSi {
    
    static People liSi = () -> {
        System.out.println("i am lisi");
    };
}
           

我們可以嘗試調用一下liSi的say方法。

public class LiSi {

    static People liSi = () -> {
        System.out.println("i am lisi");
    };

    public static void main(String[] args) {
        liSi.say();
    }
}
           

輸出結果: i am lisi

其中 () 是參數清單,這裡沒有使用參數。 ->是操作符,固定格式不必糾結,{}是方法體。

看到這裡你可能會有一點疑惑,我們在定義liSi這個對象的時候,也沒有指定它的say方法啊,為什麼調用say方法的時候可以實作呢?這就涉及到函數式接口的定義:

有且僅有一個抽象方法

。是以在建立lisi的時候,方法體裡實作的就是People接口裡的say方法。

當方法體裡隻有一個表達式的時候,方法體的大括号也可以省略不寫

。就像這樣:

我們通常通過

@FunctionalInterface

來标示一個函數式接口,也可以不寫,它隻是起到一個标示作用。

此時lisi就是一個People對象,

且實作了唯一的抽象方法

。現在有一個

talk

方法,需要Peopeo參數:

public static void talk(People people) {
    people.say();
}
           

我們在調用的時候就可以用

lambda表達式

進行替換【了解這一點非常重要,搞清楚這個很友善接下來學習lamda的常用方法和流式程式設計】:

public static void main(String[] args) {
    talk(() -> System.out.println("i am lisi"));
}
           

因為

talk

方法需要的參數是People,而我們的

() -> System.out.println("i am lisi")

則正是一個實作了People接口唯一抽象方法的執行個體。此時運作則會輸出:

i am lisi

了解這一點則可以開始接下來的學習,lambda常用方法.

連結: