本文首發:
Java-函數式編程(二)Lambda表達式html
「Lambda 表達式」(lambda expression)是一個匿名函數,Lambda表達式基於數學中的λ演算得名,直接對應於其中的lambda抽象(lambda abstraction),是一個匿名函數,即沒有函數名的函數。Lambda表達式能夠表示閉包(注意和數學傳統意義上的不一樣)。java
public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("匿名內部類的執行"); } }).start(); }
設計匿名內部類的目的,就是爲了方便程序猿將代碼做爲數據來傳遞。可是你會發現,這個對象看起來是不少餘的,因此咱們不想傳入對象,只想傳入行爲。express
new Thread(()->{ System.out.println("lambda代替內部類"); }).start();
和實現某接口的對象不一樣,咱們傳入了一段代碼塊--一個沒有名字的函數。->
將參數和表達式主體分開,左邊是參數,右邊是方法體。編程
Runnable runnable = ()-> System.out.println("hello world");
該Lambda表達式不包含參數(由於是空括號)。閉包
interface Test{ void oneParam(String name); } Test test = s -> System.out.println("oneParam方法傳遞參數:"+s); test.oneParam("我是傳遞的值");
控制檯輸出:
oneParam方法傳遞參數:我是傳遞的值
(lambda只能用於函數式接口),若是參數只包含一個參數,能夠省略參數的括號。ide
interface Test2{ int add(int a,int b); } Test2 test2 = (x,y) -> x+y; int add = test2.add(10, 10); System.out.println(add);
控制檯輸出:
20
能夠看到,咱們在使用lambda的時候建立了一個函數x+y
,Test2
對象不是表示兩個數字的和,而是表示兩個數字相加的代碼。以上的代碼中,參數類型都是由編譯器本身推斷的,一樣,咱們能夠明確的聲明參數類型:函數式編程
interface Test3{ long add(long a,long b); } Test3 test3 = (long x,long y) -> x+y; long add = test3.add(10, 10);
Error:(25, 64) java: 從lambda 表達式引用的本地變量必須是最終變量或實際上的最終變量函數
String name = "FantJ"; Runnable runnable = ()-> System.out.println("hello " +name); runnable.run(); hello FantJ
上面這段代碼,Lambda能夠引用非final變量這個屬性你能夠早已瞭解,可是你更須要知道,java8只是放鬆了這一語法的限制,但實際上要求該變量仍是final。spa
能夠看到,無論name
在使用lambda
的前仍是後作改動,lambda
都會報錯:表達式引用的本地變量必須是最終變量或實際上的最終變量,簡單的,咱們能夠稱他爲既成事實上的final變量。因此,lambda也被稱爲閉包。設計
java中,全部方法都有返回類型,那lambda返回類型是什麼呢。
是接口方法的返回類型。這一點前文有體現過。這裏再詳細解釋下。
interface Test{ void oneParam(String name); }
拿這個例子來說,oneParam
方法表示一種行爲:接受一個String
,返回void
。只要方法名和行爲和Lambda表達式匹配便可完成調用。
注意:若是編譯器猜不出參數和返回值的類型,則都將視爲Object
處理。