- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- 簡(jiǎn)單易懂的java8新特性之lambda表達式知識總結
從本質(zhì)上來(lái)說(shuō),它就是一個(gè)匿名函數,可以用來(lái)直接實(shí)現接口中的方法,從而簡(jiǎn)化代碼。但是Lambda有一個(gè)限制,不能實(shí)現接口中的所有方法,所以L(fǎng)ambda表達式只能用于有且僅有一個(gè)必須需要實(shí)現的方法接口,這里需要注意必須需要實(shí)現這六個(gè)字。
public interface Printer { //有一個(gè)需要實(shí)現的方法,可以使用Lambda表達式 void print(); }
public interface Printer { //有一個(gè)需要實(shí)現的方法,可以使用Lambda表達式 void print(); //這里雖然有一個(gè)方法,但接口提供了默認實(shí)現,因此不是必須要實(shí)現的 default void printDetail(){} }
public interface Printer { //有一個(gè)需要實(shí)現的方法,可以使用Lambda表達式 void print(); //這里雖然有一個(gè)需要實(shí)現的方法,但不是必須要實(shí)現的,因為toString()是Object類(lèi)中的. String toString(); }
public interface Printer { //有一個(gè)需要實(shí)現的方法,可以使用Lambda表達式 void print(); //這里雖然有一個(gè)需要實(shí)現的方法,但不是必須要實(shí)現的,因為toString()是Object類(lèi)中的. String toString(); }
像這種只有一個(gè)必須要實(shí)現的方法的接口,在java8中稱(chēng)之為函數式接口,在定義接口時(shí)可以在接口名上方加上@FunctionInterface
標簽,用于驗證此接口是否為函數式接口。如果這個(gè)接口定義好之后不是函數式接口,那么接口名處會(huì )報錯。
在使用Lambda表達式的時(shí)候,不需要關(guān)注方法名,只需要關(guān)注方法參數和返回值即可?;菊Z(yǔ)法很簡(jiǎn)單:
(參數列表)->{ 方法體 };
java中實(shí)現接口的方式在java8之前有兩種:定義接口的實(shí)現類(lèi),使用匿名類(lèi),但Lambda表達式相比于這種方法都簡(jiǎn)單很多。以上文的Printer接口為例,實(shí)現如下:
class PrinterImpl implements Printer{ @Override public void print() { System.out.println("Hello World"); } }
class PrinterAnonymous { Printer printer = new Printer() { @Override public void print() { System.out.println("Hello World"); } }; }
class PrinterLambda{ Printer p = ()-> System.out.println("Hello World"); }
比較上文三種實(shí)現方式,很顯示Lambda的實(shí)現比前兩種簡(jiǎn)單很多。
@FunctionalInterface public interface Printer { void print(); } public class Tester { public static void main(String[] args) { // 方法一,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號 Printer p1 = () -> System.out.println("Hello World 1"); p1.print(); // 方法二,標準定義 Printer p2 = () -> { System.out.println("Hello World 2"); }; p2.print(); } }
@FunctionalInterface public interface Printer { void print(String str); } public class Tester { public static void main(String[] args) { // 方法一,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號 //因為這里只有一個(gè)參數,小括號也可以省略,小括號省略的前提是:有且僅有一個(gè)參數 //Printer p1 = s -> System.out.println(s); Printer p1 = (s) -> System.out.println(s); p1.print("Hello World 1"); // 方法二,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號 Printer p2 = (String s) -> System.out.println(s); p2.print("Hello World 2"); // 方法三,標準定義 Printer p3 = (String s) -> { System.out.println(s); }; p3.print("Hello World 3"); } }
@FunctionalInterface public interface Printer { void print(String str1,String str2); } public class Tester { public static void main(String[] args) { // 方法一,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號 //參 Printer p1 = (s1,s2) -> System.out.println(s1+" "+s2); p1.print("Hello World 1","Java 1"); // 方法二,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號 Printer p2 = (String s1,String s2) -> System.out.println(s1+" "+s2); p2.print("Hello World 2","Java 2"); // 方法三,標準定義 Printer p3 = (String s1,String s2) -> { System.out.println(s1+" "+s2); }; p3.print("Hello World 3","Java 3"); } }
@FunctionalInterface public interface Printer { boolean print(); } public class Tester { public static void main(String[] args) { // 方法一,有返回值的情況,只有一條語(yǔ)句,return關(guān)鍵字的有無(wú)決定能否活力大括號 Printer p1 = () -> true; boolean has1 = p1.print(); System.out.println(has1);//測試返回結果 // 方法二,標準定義 Printer p2 = () -> {return true;}; boolean has2 = p2.print(); System.out.println(has2);//測試返回結果 } }
@FunctionalInterface public interface Printer { boolean print(boolean good); } public class Tester { public static void main(String[] args) { // 方法一,有返回值的情況,只有一條語(yǔ)句,return關(guān)鍵字的有無(wú)決定能否活力大括號 //因為這里只有一個(gè)參數,小括號也可以省略,小括號省略的前提是:有且僅有一個(gè)參數 //Printer p1 = good -> good; Printer p1 = (good) -> good; boolean has1 = p1.print(true); System.out.println(has1); // 方法二,標準定義 Printer p2 = (good) -> {return good;}; boolean has2 = p2.print(false); System.out.println(has2); } }
@FunctionalInterface public interface Printer { boolean print(boolean good1,boolean good2); } public class Tester { public static void main(String[] args) { // 方法一,有返回值的情況,只有一條語(yǔ)句,return關(guān)鍵字的有無(wú)決定能否活力大括號 Printer p1 = (good1,good2) -> good1; boolean has1 = p1.print(true,false); System.out.println(has1); // 方法二,標準定義 Printer p2 = (good1,good2) -> {return good1;}; boolean has2 = p2.print(false,false); System.out.println(has2); } }
在實(shí)現一個(gè)接口的方法時(shí),如果現有的其他地方的某個(gè)函數已經(jīng)實(shí)現了接口方法的邏輯,可以使用方法引用直接將這個(gè)邏輯引用過(guò)來(lái)。
語(yǔ)法:
接口名 變量名 = 類(lèi) ::已實(shí)現的方法
注意事項:
示例:
Printer 需要實(shí)現的方法在Checker中有同樣的實(shí)現,這樣就可以直接引用過(guò)來(lái)
@FunctionalInterface public interface Printer { String print(boolean good1,boolean good2); } public class Checker { public static String check(boolean a,boolean b) { if(a && b) { return "Java is good"; }else if (!a && b) { return "Java is better"; } return "Java is best"; } } public class Tester { public static void main(String[] args) { Printer p1 = Checker::check;//用類(lèi)名來(lái)引用 System.out.println(p1.print(true, true)); } }
語(yǔ)法:
接口名 變量名 = 對象 ::靜態(tài)方法
注意事項:
示例:
Printer 需要實(shí)現的方法在Checker中有同樣的實(shí)現,這樣就可以直接引用過(guò)來(lái)
@FunctionalInterface public interface Printer { String print(boolean good1,boolean good2); } public class Checker { public String check(boolean a,boolean b) { if(a && b) { return "Java is good"; }else if (!a && b) { return "Java is better"; } return "Java is best"; } } public class Tester { public static void main(String[] args) { Printer p1 = new Checker()::check;//必須用對象來(lái)引用 System.out.println(p1.print(true, true)); } }
如果一個(gè)函數式接口中定義的方法僅僅是為了得到一個(gè)對象,此時(shí)我們就可以使用構造方法的引用,簡(jiǎn)化這個(gè)方法的實(shí)現
語(yǔ)法:
接口名 變量名 = 類(lèi)名 ::new
注意事項:
可以通過(guò)接口中的方法參數,區分引用不同的構造方法
示例:
@FunctionalInterface public interface Printer1 { Checker getCheck(); } @FunctionalInterface public interface Printer2 { Checker getCheck(int a); } public class Checker { int times; public Checker() { System.out.println("I am none parameter"); } public Checker(int a) { System.out.println("I have one parameter"); } } public class Tester { public static void main(String[] args) { //引用無(wú)參構造方法 Printer1 p1 = Checker::new; p1.getCheck(); //引用有參構造方法 Printer2 p2 = Checker::new; p2.getCheck(1); } }
如果實(shí)現某些接口的時(shí)候,Lambda表達式中包含了某一個(gè)對象,此時(shí)方法體中,直接使用這個(gè)對象調用它的某一個(gè)方法就可以完成整個(gè)的邏輯。其他的參數,可以作為調用方法的參數。此時(shí),可以對這種實(shí)現進(jìn)行簡(jiǎn)化。
示例:
@FunctionalInterface public interface Printer1 { int getCheck(Checker checker); } @FunctionalInterface public interface Printer2 { void setCheck(Checker checker, int a); } public class Tester { public static void main(String[] args) { Checker checker = new Checker(); checker.setTimes(100); // 沒(méi)有簡(jiǎn)化前,按照之前的方法使用lambda表達式 Printer1 p1 = x -> x.getTimes(); System.out.println(p1.getCheck(checker));//測試 // 簡(jiǎn)化之后 Printer1 p11 = Checker::getTimes; System.out.println(p11.getCheck(checker));//測試 // 沒(méi)有簡(jiǎn)化前,按照之前的方法使用lambda表達式 Printer2 p2 = (x,y)-> x.setTimes(y); p2.setCheck(checker, 50); System.out.println(checker.getTimes());//測試 // 簡(jiǎn)化之后 Printer2 p22 = Checker::setTimes; p22.setCheck(checker, 30); System.out.println(checker.getTimes());//測試 } }
當在Lambda表達式中使用了某一個(gè)局部變量,那么這個(gè)局部變量的值在Lambda表達式之外,不可以被改變,因為默認將其定義成final常量。但全局變量變量沒(méi)有這方面的限制。
示例:
@FunctionalInterface public interface Printer { void setTime(); } public class Tester { public static void main(String[] args) { int time = 10; Printer p = () -> System.out.println(time);//這里出錯了,因為下一行對time進(jìn)行修改 time = 15;//這里的值不能改變,會(huì )導致上一行出錯 } }
基本概括了Lambda表達式的所有用法,不足之處,請諒解,謝謝!
到此這篇關(guān)于簡(jiǎn)單易懂的java8新特性之lambda表達式知識總結的文章就介紹到這了,更多相關(guān)java lambda表達式內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站