1、函數式接口:只定義了單一抽象方法的接口,用做Lambda表達式的類型java
註解@FunctionalInterface用於Service代表Service接口是一個函數式接口,這裏須要強調的是:函數式接口只能有一個抽象方法,而不是隻能有一個方法。函數
2、使用default關鍵字,能夠在接口內定義實例方法,這個方法並不是抽象方法,而是擁有特定邏輯的具體實例方法,具體的實現類中不是必須重寫默認方法測試
3、Lambda表達式即匿名函數,它是一段沒有函數名的函數體,能夠做爲參數直接傳遞給相關的調用者.this
4、Lanbda表達式的語法spa
(Type1 param1, Type2 param2, ..., TypeN paramN) -> { statment1; statment2; //............. return statmentM; }
表達式使用 "->"將參數和主體分開, -> 前面是參數部分,後面這是主體部分對象
說明:用正常的函數來講明接口
Type:是具體參數的類型get
param:是具體參數名編譯器
{ }:方法體io
statment:方法體重具體的代碼處理邏輯
return:方法體中的返回值
一、lambda表達式沒有參數,使用空括號()表示沒有參數:
() -> { //..... };
二、lambda表達式只有一個參數,可省略參數括號和參數類型,javac能根據上下文推斷出參數類型。
param1 -> { statment1; statment2; //............. return statmentM; }
三、當lambda表達式只包含一條語句時,能夠省略大括號{}。
param1 -> statment
四、參數類型省略–絕大多數狀況,編譯器均可以從上下文環境中推斷出lambda表達式的參數類型。
(param1,param2, ..., paramN) -> { statment1; statment2; //............. return statmentM; }
5、方法引用
方法引用是Java8中提出的用來簡化Lambda表達式的一種手段,它經過類名和方法名來定位一個靜態方法或者實例方法。方法引用使用"::"定義,"::"的前半部分表示類名或者實例名,後半部分表示方法名稱,若是是構造器函數,則使用new表示。
一、靜態方法引用:ClassName::methodName
List<String> strs = Arrays.asList("aa","bb","cc"); strs.forEach(System.out::println);
輸出結果:
class Printer { void print() { System.out.println("instanceRefence::methodName"); } private void printInfo() { //實例方法引用 new Thread(this::print); } } //測試 private void test () { Printer p = new Printer(); p.print(); }
輸出結果:
public class Test { class User { String username; User(String username) { this.username = username; } public String getUsername() { return username; } } @FunctionalInterface interface UserFactory<T extends User> { T create(String username); } public static void main(String[] args) { Test t = new Test(); t.test(); } private void test() { UserFactory<User> uf = User::new; List<User> users = new ArrayList<>(); for (int i = 0; i < 5; ++i) { users.add(uf.create("user" + i)); } users.stream().map(User::getUsername).forEach(System.out::println); } }
UserFactory做爲User的工廠類,是一個函數式接口。當使用User::new建立接口實例時,系統會根據UserFactory.create()的函數簽名選擇合適的User構造函數。在建立UsrFactory實例後,對UsrFactory.create()的調用都會委託給User的實際構造函數進行,從而建立User對象實例。User::getUsername表示User類的實例方法。
輸出結果: