初識Lambda表示式1----java
阿新 • • 發佈:2018-11-26
寫在前面的話
終於還是換了新的工作,比起原來每天早上8:00上班晚上12點多才回宿舍的日子,現在真的幸福的不止一點半點。但真正讓我最開心的是公司裡有很多的大牛,也用了很多的新技術,而現在我也有相對比較充足的時間去給自己充電,希望自己能夠通過不懈的努力更快的成為一個大牛。
首先我想啃的是lambda表示式。
首先看如下程式碼:
package com.nrsc.lambda;
interface Interface1 {
int calculate(int i);
}
class Test implements Interface1 {
@Override
public int calculate(int i) {
System.out.println("-----繼承----");
return i * 2 + 4;
}
}
public class LambdaDemo1 {
public static void main(String[] args) {
Interface1 test = new Test();
int value = test.calculate(3);
System.out.println (value);
}
}
執行結果如下:
上面的程式碼很簡單,就是有一個類Test繼承了一個介面Interface1 並實現了Interface1內的calculate方法,然後在LambdaDemo1 類中new一個Test類就可以完成對該方法的呼叫。
再看一下lambda表示式與上面方式的對比
package com.nrsc.lambda;
interface Interface1 {
int calculate(int i);
}
class Test implements Interface1 {
@Override
public int calculate(int i) {
System.out.println("-----繼承----");
return i * 2 + 4;
}
}
public class LambdaDemo1 {
public static void main(String[] args) {
Interface1 test = new Test();
int value = test.calculate(3);
System.out.println(value);
System.out.println("=========割========");
/**
* Lambda表示式
*/
Interface1 i1 = (i) -> i * 1;
//與繼承的方式進行對比可以知道lambda表示式中
// "->"左邊是介面中方法需要輸入的引數,
// "->"右邊是繼承了該介面的類對介面中定義方法的一個具體實現
// 而"="號右邊所有的內容加起來就是構建了一個實現了Interface1介面的例項(多型)
int i1Value = i1.calculate(3); //返回值型別就是介面內方法的返回值型別
System.out.println(i1Value);
}
}
lambda表示式還有如下幾種書寫方式
package com.nrsc.lambda;
//@FunctionalInterface為一個編譯註解--標誌本介面為函式式介面,不寫也不會報錯
//但建議能加的時候還是加上
//這裡有一個注意點,假如加上了該註解,那麼這個介面就必須有一個未實現的方法
//否則會報編譯錯誤 No target method found
@FunctionalInterface
interface Interface1 {
int calculate(int i);
// int add(int i, int j); //@FunctionalInterface會報編譯錯誤,因為被此註解標註的介面,只能有一個未實現的方法
}
class Test implements Interface1 {
@Override
public int calculate(int i) {
System.out.println("-----繼承----");
return i * 2 + 4;
}
}
public class LambdaDemo1 {
public static void main(String[] args) {
Interface1 test = new Test();
int value = test.calculate(3);
System.out.println(value);
System.out.println("=========割========");
//與繼承的方式進行對比可以知道lambda表示式中
// "->"左邊是介面中方法需要輸入的引數,
// "->"右邊是繼承了該介面的類對介面中定義方法的一個具體實現
// 而"="號右邊所有的內容加起來就是構建了一個實現了Interface1介面的例項(多型)
/**
* Lambda表示式常見寫法如下
*/
Interface1 i1 = (i) -> i * 1;
Interface1 i2 = i -> i * 2 + 1; //比較簡單且常見的寫法
Interface1 i3 = (int i) -> i * 3 + 2;
//前三種方式預設有一個return,下面這種方式可以顯示寫出要return的內容
//並且還可以有一些中間操作,如下面的輸出語句
Interface1 i4 = i -> {
System.out.println("---------");
return i * 4 + 3;
};
int i1Value = i1.calculate(3); //返回值就是介面內方法的返回值
System.out.println(i1Value);
System.out.println(i2.calculate(2));
System.out.println(i3.calculate(2));
System.out.println(i4.calculate(2));
}
}
注意
Interface1介面上的註解@FunctionalInterface,它放在某個介面上的話,該介面只能有一個未實現的方法(java官方鼓勵一個介面只幹一件事),但是還可以有一些預設實現的方法,如下:
package com.nrsc.lambda;
//@FunctionalInterface為一個編譯註解--標誌本介面為函式式介面,不寫也不會報錯
//但建議能加的時候還是加上
@FunctionalInterface
interface Interface2 {
int calculate(int i);
// int add(int i, int j); //@FunctionalInterface會報編譯錯誤,因為被此註解標註的介面,只能有一個未實現的方法
//但是函式式介面可以有一個或多個預設實現的方法,如下:
default int plus(int x, int y) {
System.out.println("預設方法加");
return x + y;
}
default int minus(int x, int y) {
System.out.println("預設方法減");
return x - y;
}
}
public class LambdaDemo2 {
public static void main(String[] args) {
Interface2 i1 = i -> i * 3;
System.out.println(i1.minus(5, 4));
System.out.println(i1.plus(5, 4));
System.out.println(i1.calculate(5));
}
}
還有一個知識點需要補充一下,當兩個函式式介面都預設實現了某個方法時(如plus),如果第三個介面想繼承這兩個介面時,必須得指定要繼承哪個介面的預設實現方法,當然它也可以重新實現這個預設方法.
package com.nrsc.lambda;
//@FunctionalInterface為一個編譯註解--標誌本介面為函式式介面,不寫也不會報錯
//但建議能加的時候還是加上
@FunctionalInterface
interface Interface11 {
int calculate(int i);
//但是函式式介面可以有一個或多個預設實現的方法,如下:
default int plus(int x, int y) {
System.out.println("預設方法加");
return x + y;
}
}
@FunctionalInterface
interface Interface12 {
int calculate(int i);
//但是函式式介面可以有一個或多個預設實現的方法,如下:
default int plus(int x, int y) {
System.out.println("預設方法加");
return x + y;
}
}
@FunctionalInterface
interface Interface13 extends Interface11, Interface12 {
//int minus (int i); //---- 如果加上這句話肯定也會報錯,因為FunctionalInterface標註的類只能有一個未實現的方法
//---- 而且假如Interface11和Interface12中未實現的方法(calculate)不是一個,肯定也會報錯
//如果繼承的兩個接口裡有相同的預設方法的話,必須得選擇繼承哪一個的
@Override
default int plus(int x, int y) {
return Interface11.super.plus(x, y);
}
//下面這種方式也可以
/* @Override
default int plus(int x, int y) {
return x + y;
}*/
}
public class LambdaDemo3 {
public static void main(String[] args) {
Interface13 i1 = i -> i * 3;
System.out.println(i1.plus(5, 4));
System.out.println(i1.calculate(5));
}
}