1. 程式人生 > >Java8 Lambda( -> )&&方法引用( :: )&&函式式介面(@Functional)

Java8 Lambda( -> )&&方法引用( :: )&&函式式介面(@Functional)

一、簡述

Java8之前建立一個執行緒的程式碼:

new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Test");
            }
        });

其中Runnable就是一個匿名內部類,一般在一個執行緒只出現一次但必須實現。

再看Runnable的程式碼實現,就是一個Functional Interfaces函式式介面:

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

 

 在上面的程式碼中只定義了一個抽象方法,這樣的介面,被稱為函式式介面Functional Interface;JDK裡有很多,如Predicate,Comparator。

Lambda表示式主要就是用於定義一個函式式介面的內聯實現,如 Runnable r = ()-> System.out.println("Test"); ,我們用Lambda表示式實現了Runnable介面。

所以建立執行緒可以簡寫成 new

Thread(()->System.out.println("Test")) 。

至於方法引用,他只是一種更簡單的lambda表示式,提供了一種引用而不執方法的方式。

String::valueOf   等價於lambda表示式 (s) -> String.valueOf(s)

 

 Lambda,Functional Interface,MethodReference,也有很多規則和約束。

二、規則

1、Lambda

Lambda表示式具有如下特徵:

  • 【可選】型別宣告:引數的型別不需要宣告,編譯器可以根據引數值推斷出其型別;
  • 【可選】括號:單個引數的話,不需要用圓括號包圍引數,當然,對於多個引數或無引數的話,括號是需要的;
  • 【可選】花括號:如果表示式主體只有一條語句的話,不需要用花括號包圍,當然,對於多條語句,花括號是需要的;
  • 【可選】return關鍵字:如果表示式主體是單一表達式,return關鍵字可以不寫,編譯器可以自動返回該值,當然,如果寫了return,則需要加上花括號;

2、函式式介面

  • 只能有一個抽象方法
  • @FunctionalInterface,主要用於編譯級錯誤檢查,當你寫的介面不符合函式式介面定義的時候,編譯器會報錯,加不加@FunctionalInterface對於介面是不是函式式介面沒有影響
  • 可以包含預設方法,因為預設方法不是抽象方法,其有一個預設實現,所以是符合函式式介面的定義的;default關鍵字
  • 可以包含靜態方法,因為靜態方法不能是抽象方法,是一個已經實現了的方法,所以是符合函式式介面的定義的;
  • 可以包含Object裡的public方法,這些方法對於函式式介面來說,不被當成是抽象方法(雖然它們是抽象方法);因為任何一個函式式介面的實現,預設都繼承了Object類,包含了來自java.lang.Object裡對這些抽象方法的實現;

3、方法引用

四種方法引用型別

型別 示例
引用靜態方法 ContainingClass::staticMethodName
引用某個物件的例項方法 containingObject::instanceMethodName
引用某個型別的任意物件的例項方法 ContainingType::methodName
引用構造方法 ClassName::new

 

 

 

 

 

a、靜態方法引用

就是靜態方法可以用

b、特定物件例項方法

Student s = new Student()

Arrays.sort(students,s::getAge)


super::methodName
this :: equals

 

c、任意物件的例項方法引用

String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);

 

d、構造方法引用

String::new, 等價於lambda表示式 () -> new String() 

int[]::new 是一個含有一個引數的構造器引用,這個引數就是陣列的長度。等價於lambda表示式  x -> new int[x]