java Lambda表達式的使用心得
Lambda表達式的心得
如題,因為博主也是最近才接觸到Lambda表達式的(PS 在這裡汗顏一會)。我並不會講解它的原理,誠然任何一件事物如果理解原理的話,使用它必將更加容易。但博主在學習的時候,大多數時候都是學會怎麼用,然後在細究原理。就像你騎自行車之前,難道首先還要研究自行車的原理麼?
首先Lambda表達式的最簡單應用如下
Lambda表達式法
String lam= "初次相識Lambda"; new Thread(() -> System.out.println(lam)).start();
傳統方法
String tradition="傳統方法"; new Thread(new Runnable() { @Override public void run() { System.out.println(tradition); } }).start();
輸出結果
很簡潔有沒有?省略瞭好多代碼是不是,在這裡 你可以發現”,Lambda表達式和在Thread創建一個匿名類的作用是一樣。我們可以這樣認為Lambda表達式本身代表瞭一個匿名類。
這就是Lambda最大的作用,當然Lambda表達式隻能創建接口interface對象。 創建類是不行的,抽象類也是不行的 ,隻要是類都是不行的。
首先,我定義瞭一個自定義的接口,可以用來測試
@FunctionalInterface public interface Lam { //Lambda表達式調用的方法 void bda(); //接口的默認方法 default void test(){ System.out.println("我是默認的方法"); }; //接口的靜態方法 static void test1(){ System.out.println("我是靜態方法"); } }
使用Lambda表達式 你首先要知道的
1.Lambda表達式隻能是接口 interface的創建(PS從上面的例子可以看出來,Runnable是接口,可以查看源代碼),並且這個接口隻能包含一個方法(除瞭default方法和static方法)。在接口中創建default方法和static方法都必須要實現方法體如下圖
2.如果你用Lambda表達式來創建類 class,則會出現以下錯誤 ”Target type of a lambda conversion must be an interface“如果你怕自己的定義的接口不符合Lambda表達式的規范 ,你可以在接口interfaca 上面添加註解@FunctionalInterface
3.Lambda表達式的規范表示格式 (parameters) ->{ statements; }。在某些時刻,你還可以簡化這個格式
//接口定義的方法無參數時候,並且你想要執行操作也隻有一句代碼的時候,Lambda會自動返回一句代碼,並且可以不用加{} Lam lam1=()->System.out.println("無參數");
你可以發現後面的大括號{ }沒瞭,這是因為後面代碼如果隻有一句的話,是可以省略{ } 的
我們把Lam接口定義的調用方法參數修改一下,多出瞭一個String類型的形參s
//Lambda表達式調用的方法 void bda(String s);
這時候 我們如果使用Lambda表達式,則可以這樣
//接口定義的方法有參數時候,並且你想要執行的操作也隻有一句代碼的時候 Lam lam1=e->System.out.println(e);//這一句還有簡化版本 Lam lam1=System.out::println; lam1.bda("4556");
你又會發現,前面的()中括號也沒瞭,這是因為當參數隻有一個的時候,是可以省略()的。
當然也有你要執行很多代碼的時候,那這時候可以這樣
//接口定義的方法有參數時候,並且你想要執行的操作有很多句代碼的時候 Lam lam1 = (String e) -> { String a = e + "add"; System.out.println(a); }; lam1.bda("test+");
輸出結果如下
當然你還會問Lambda表達式能不能返回東西呢?這是肯定能的,首先我們再把上面的Lam接口方法修改一下
//Lambda表達式調用的方法 String bda(String s);
讓bda方法返回一個String值,這次如果我們用Lambda的話
//接口定義的方法有返回值的時候 Lam lam1=s ->{System.out.println(s);return "我是返回的數據";}; lam1.bda("test1"); System.out.println(lam1.bda("test2"));
運行的結果:
總結 Lambda表達式 就是用來創建一個匿名的接口對象,即 它本身就是一個接口的匿名實例。隻不過這個接口 有一些條件限制。
Lambda表達式的技巧
Lambda表達式隻能用來簡化僅包含一個public方法的接口的創建
規則
- 1.隻能是接口
- 否則報:Target type of a lambda conversion must be an interface
- 2.隻能有一個public方法
- 否則報:Multiple non-overriding abstract methods found AInterface
- 或AInterface is not a functional interface
括號形式
testA((int i, int j) -> {});參數要與接口一致
public class Go { public static void main(String a[]) { //正確示范 testA((int i, int j) -> {}); //錯誤示范:Multiple non-overriding abstract methods found xxx;隻能有一個public方法 testB((int i, int j) -> {}); //錯誤示范:Target type of a lambda conversion must be an interface;隻能是接口 testC((int i, int j) -> {}); } public static void testA(AInterface t) { } public static void testC(CInterface t) {} public static void testB(BInterface t) {} interface AInterface { void xxx(int i, int j); } interface BInterface { void xxx(int i, int j); void YYY(int i, int j); } abstract class CInterface { abstract void xxx(int i, int j); } }
雙冒號表達形式
- 雙冒號後面必須是靜態方法
- 否則報錯:Non-static method cannot be referenced from a static context
- 雙冒號後面的方法與接口方法參數一樣
- 方法與接口的權限可以不一樣
- 返回類型:如果接口裡面方法是void,雙冒號後的方法可以任意返回類型,否則要一致
public class Go { public static void main(String a[]) { //之前的寫法 testA(new AInterface() { @Override public void xxx(int i, int j) { } }); //正確,相對與接口裡面xxx方這是改成靜態和換瞭個名字 testA(Go::mydog); //正確,加瞭返回類型和public換成private,也是ok testA(Go::mydog2); //錯誤:Non-static method cannot be referenced from a static context testA(Go::mydog3); //這樣寫也是ok的。 AInterface aInterface = Go::mydog; testA(aInterface); } public static void testA(AInterface t) { t.xxx(1, 2); } interface AInterface { void xxx(int i, int j); } public static boolean mydog(int i, int j) { System.out.println("mydog" + i + " & " + j); return false; } private static void mydog2(int i, int j) { System.out.println("mydo2" + i + " & " + j); } public void mydog3(int i, int j) { System.out.println("mydog3" + i + " & " + j); } }
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Java創建線程及配合使用Lambda方式
- Java lambda表達式與泛型整理總結
- Java8語法糖之Lambda表達式的深入講解
- 關於JavaEE匿名內部類和Lambda表達式的註意事項
- Java中Lambda表達式的使用詳細教程