1. 程式人生 > >Java8函數語言程式設計入門

Java8函數語言程式設計入門

雖然最近java9都已經發布了。但是目前很多同學連java8都沒有用到。
java8增加了很多有用的特性,對於大家的程式設計還是有很大幫助的。沒有用過java8的同學還是非常有必要了解一下這些新特性的。

java8有個很重要的改變:增加了函數語言程式設計(Lambda表示式)。
相比以前的Java新特性,lambda表示式對於從沒接觸函數語言程式設計的Java程式設計師來說,並不是很好理解。因此我這兒特意一些分享,希望能對沒有用過的同學有所幫助。

為什麼要有lambda表示式? 引用大師的原話”未來的程式語言將逐漸融合各自的特性,而不存在單純的宣告式語言(如之前的Java)或者函式程式語言。將來宣告式程式語言借鑑函式程式設計思想,函式程式語言融合宣告式程式設計特性…這幾乎是一種必然趨勢”。

什麼是Lambda表示式

  • 把函式當成引數在java方法中傳遞.

以往我們的java方法只能是傳遞一個值或者引用, 如:

test.hello("hello world");//引數只能是傳遞值

而在lambda表示式裡,可以這樣:

Thread thread = new Thread(() -> System.out.println("hello world"));
thread.start();

new Thread()引數傳遞的就是一個行為,列印”hello world”.

  • lambda表示式必須依附於一類特別的物件型別-函式式介面FunctionalInterface
    。 比如上面的new Thread()方法就接收一個Runnable藉口做為引數,在Java8中Runnable介面就是一個函式式介面。
  • 傳遞行為,而不是值;
  • 提升抽象層次,API重用性更好。

第一個例子

//1. 定義一個函式式介面(後面會詳細講解函式式介面)
@FunctionalInterface
interface Interface1 {
    void test();
}

//2. 定義一個方法, 接受Interface1作為引數
public void testMethod(Interface1 interface1){
    interface1.test();
}

//3. 呼叫上面定義的方法: 注意,此時我們並沒有實現Interface1,但可以正確執行程式碼
public static void main(String[] args){ Test test = new Test(); test.testMethod(() -> System.out.println("hello world")); }

main方法裡面,呼叫test.testMethod()方法時,傳遞一個行為:列印”hello world”。
這就是一個最基本的lambda表示式的例子.

lambda表示式的基本結構:

(argument) -> {body}

(arg1, arg2…) -> {}
(type1 arg1,type2 arg2…) -> {body}
示例說明:
(int a,int b) -> {return a+b}
() -> System.out.println(“Hello world”);
(String s) -> {System.out.println(s);}
() -> “Hello world”
() -> {return “Hello world”;}
1. 一個lambda表示式可以有零個或多個引數
2. 引數的型別可以明確宣告,也可以根據上下文來推斷。(int a) 與 (a)
3. 所有引數需要包含在括號內,引數之前用逗號隔開
4. 括號代表引數集為空。例如() -> “Hello world”
5. 當只有一個引數,型別可以推導,()可以省略。a-> {body}
6. lambda表示式的主體可以包含零或者多條語句
7. 如果lambda表示式主體只有一條語句, {}可以省略
8. 如果lambda表示式的主體包含一條以上語句, 則表示式必須包含在{}中。匿名函式返回型別與程式碼塊的返回型別一致

函式式介面funcationalInterface:

1, 一個介面有且僅有一個抽象方法稱為函式式介面。
2, 如果我們在某個介面上聲明瞭functionalInterface, 那麼編譯器就會按照函式式介面的定義來要求介面,不滿足定義的就會報錯
3, 如果某個介面只有一個抽象方法,但我們並沒有給該介面宣告functionalinterface註解,那麼編譯器依舊會將該介面看作是函式式介面
4, 如果介面中的一個方法是覆寫的java.lang.Object的方法,這個方法不計劃在函式式方法的個數內.
5, 函式式介面可以通過Lambda表示式,方法引用,構造器引用來實現.
6,注意在java8,介面可以包含實現的default方法. 如List接口裡就有這樣一個default方法。

default void replaceAll(UnaryOperator<E> operator) {
    Objects.requireNonNull(operator);
    final ListIterator<E> li = this.listIterator();
    while (li.hasNext()) {
        li.set(operator.apply(li.next()));
    }
}

lambda表示式最基本的入門就講完了。後面逐步深入介紹。