Java中Lambda表達(dá)式使用場景實例詳解
Java中Lambda表達(dá)式使用及詳解
前言
一、Lambda表達(dá)式的簡介
Lambda表達(dá)式(閉包):java8的新特性,lambda運行將函數(shù)作為一個方法的參數(shù),也就是函數(shù)作為參數(shù)傳遞到方法中。使用lambda表達(dá)式可以讓代碼更加簡潔。
Lambda表達(dá)式的使用場景:用以簡化接口實現(xiàn)。
關(guān)于接口實現(xiàn),可以有很多種方式來實現(xiàn)。例如:設(shè)計接口的實現(xiàn)類、使用匿名內(nèi)部類。 但是lambda表達(dá)式,比這兩種方式都簡單。
package test;
/**
* @author: Mercury
* Date: 2022/3/20
* Time: 17:48
* Description:Lambda表達(dá)式
* Version:1.0
*/
public class Test04 {
public static void main(String[] args) {
//使用lambda表達(dá)式實現(xiàn)接口
Test test = () -> {
System.out.println("test");
};
test.test();
}
}
interface Test{
public void test();
}二、Lambda表達(dá)式對接口的要求
雖然說,lambda表達(dá)式可以在?定程度上簡化接口的實現(xiàn)。但是,并不是所有的接口都可以使用lambda表達(dá)式來簡潔實現(xiàn)的。
lambda表達(dá)式畢竟只是?個匿名方法。當(dāng)實現(xiàn)的接口中的方法過多或者多少的時候,lambda表達(dá)式都是不適用的。
lambda表達(dá)式,只能實現(xiàn)函數(shù)式接口。
1.函數(shù)式接口
如果說,?個接口中,要求實現(xiàn)類必須實現(xiàn)的抽象方法,有且只有?個!這樣的接口,就是函數(shù)式接口。
代碼如下(示例):
//有且只有一個實現(xiàn)類必須要實現(xiàn)的抽象方法,所以是函數(shù)式接口
interface Test{
public void test();
}
2.@FunctionalInterface
是?個注解,用在接口之前,判斷這個接口是否是?個函數(shù)式接口。 如果是函數(shù)式接口,沒有任何問題。如果不是函數(shù)式接口,則會報錯。功能類似于 @Override。
代碼如下(示例):
@FunctionalInterface
interface Test{
public void test();
}
3.Lambda表達(dá)式的語法
1.Lambda表達(dá)式的基礎(chǔ)語法
lambda表達(dá)式,其實本質(zhì)來講,就是?個匿名函數(shù)。因此在寫lambda表達(dá)式的時候,不需要關(guān)心方法名是什么。
實際上,我們在寫lambda表達(dá)式的時候,也不需要關(guān)心返回值類型。
我們在寫lambda表達(dá)式的時候,只需要關(guān)注兩部分內(nèi)容即可:參數(shù)列表和方法體
lambda表達(dá)式的基礎(chǔ)語法:
(參數(shù)1,參數(shù)2,…) -> {
方法體
};
參數(shù)部分:方法的參數(shù)列表,要求和實現(xiàn)的接口中的方法參數(shù)部分?致,包括參數(shù)的數(shù)量和類型。
方法體部分 : 方法的實現(xiàn)部分,如果接口中定義的方法有返回值,則在實現(xiàn)的時候,注意返回值的返回。
-> : 分隔參數(shù)部分和方法體部分。
代碼示例:
package test;
/**
* @author: Mercury
* Date: 2022/3/20
* Time: 17:48
* Description:Lambda表達(dá)式
* Version:1.0
*/
public class Test04 {
public static void main(String[] args) {
//使用lambda表達(dá)式實現(xiàn)接口
//無參
// Test test = () -> {
// System.out.println("test");
// };
//有參
// Test test = (name,age) -> {
// System.out.println(name+age+"歲了!");
// };
// test.test("小新",18);
//有參+返回值
Test test = (name,age) -> {
System.out.println(name+age+"歲了!");
return age + 1;
};
int age = test.test("小新",18);
System.out.println(age);
}
}
//無參
//interface Test{
// public void test();
//}
//有參 無返回值
//interface Test{
// public void test(String name,int age);
//}
//有參 有返回值
interface Test{
public int test(String name,int age);
}4.Lambda表達(dá)式的語法進階
參數(shù)部分的精簡
參數(shù)的類型
由于在接口的方法中,已經(jīng)定義了每?個參數(shù)的類型是什么。而且在使用lambda表達(dá)式實現(xiàn)接口的時候,必須要保證參數(shù)的數(shù)量和類 型需要和接口中的方法保持?致。因此,此時lambda表達(dá)式中的參數(shù)的類型可以省略不寫。
注意點:
如果需要省略參數(shù)的類型,要保證:要省略, 每?個參數(shù)的類型都必須省略不寫。絕對不能出現(xiàn),有的參數(shù)類型省略了,有的參數(shù)類型沒有省略。
//有參+返回值
Test test = (name,age) -> {
System.out.println(name+age+"歲了!");
return age + 1;
};
int age = test.test("小新",18);
System.out.println(age);
參數(shù)的小括號
如果方法的參數(shù)列表中的參數(shù)數(shù)量 有且只有?個,此時,參數(shù)列表的小括號是可以省略不寫的。
注意事項:
- 只有當(dāng)參數(shù)的數(shù)量是?個的時候, 多了、少了都不能省略。
- 省略掉小括號的同時, 必須要省略參數(shù)的類型
//一個參數(shù)
Test test = name -> {
System.out.println(name+"test");
};
test.test("小新");
方法體部分的精簡
方法體?括號的精簡
當(dāng)?個方法體中的邏輯,有且只有?句的情況下,?括號可以省略
Test test = name -> System.out.println(name+"test");
test.test("小新");
return的精簡
如果?個方法中唯?的?條語句是?個返回語句, 此時在省略掉大括號的同時, 也必須省略掉return。
Test test = (a,b) -> a+b;
三、函數(shù)引用
lambda表達(dá)式是為了簡化接口的實現(xiàn)的。在lambda表達(dá)式中,不應(yīng)該出現(xiàn)比較復(fù)雜的邏輯。如果在lambda表達(dá)式中出現(xiàn)了過于復(fù)雜的邏輯,會對程序的可讀性造成非常大的影響。如果在lambda表達(dá)式中需要處理的邏輯比較復(fù)雜,?般情況會單獨的寫?個方法。在lambda表達(dá)式中直接引用這個方法即可。
函數(shù)引用:引用?個已經(jīng)存在的方法,使其替代lambda表達(dá)式完成接口的實現(xiàn)
1.靜態(tài)方法的引用
語法:類::靜態(tài)方法
注意事項:
- 在引用的方法后面,不要添加小括號。
- 引用的這個方法,參數(shù)(數(shù)量、類型)和返回值,必須要跟接口中定義的?致
package test;
/**
* @author: Mercury
* Date: 2022/3/20
* Time: 18:17
* Description:lambda表達(dá)式靜態(tài)方法引用
* Version:1.0
*/
public class Test05 {
public static void main(String[] args) {
//實現(xiàn)多個參數(shù),一個返回值的接口
//對一個靜態(tài)方法的引用,語法:類::靜態(tài)方法
Test1 test1 = Calculator::calculate;
System.out.println(test1.test(4,5));
}
}
class Calculator{
public static int calculate(int a,int b ){
// 稍微復(fù)雜的邏輯:計算a和b的差值的絕對值
if (a > b) {
return a - b;
}
return b - a;
}
}
interface Test1{
int test(int a,int b);
}2.非靜態(tài)方法的引用
語法:對象::非靜態(tài)方法
注意事項:
- 在引用的方法后?,不要添加小括號。
- 引用的這個方法, 參數(shù)(數(shù)量、類型) 和 返回值, 必須要跟接口中定義的?致。
package test;
/**
* @author: Mercury
* Date: 2022/3/21
* Time: 8:14
* Description:lambda表達(dá)式對非靜態(tài)方法的引用
* Version:1.0
*/
public class Test06 {
public static void main(String[] args) {
//對非靜態(tài)方法的引用,需要使用對象來完成
Test2 test2 = new Calculator()::calculate;
System.out.println(test2.calculate(2, 3));
}
private static class Calculator{
public int calculate(int a, int b) {
return a > b ? a - b : b - a;
}
}
}
interface Test2{
int calculate(int a,int b);
}3.構(gòu)造方法的引用
使用場景
如果某?個函數(shù)式接口中定義的方法,僅僅是為了得到?個類的對象。此時我們就可以使用構(gòu)造方法的引用,簡化這個方法的實現(xiàn)。
語法:類名::new
注意事項:可以通過接口中的方法的參數(shù), 區(qū)分引用不同的構(gòu)造方法。
package com.cq.test;
/**
* @author: Mercury
* Date: 2022/4/27
* Time: 10:31
* Description:lambda構(gòu)造方法的引用
* Version:1.0
*/
public class Test {
private static class Dog{
String name;
int age;
//無參構(gòu)造
public Dog(){
System.out.println("一個Dog對象通過無參構(gòu)造被實例化了");
}
//有參構(gòu)造
public Dog(String name,int age){
System.out.println("一個Dog對象通過有參構(gòu)造被實例化了");
this.name = name;
this.age = age;
}
}
//定義一個函數(shù)式接口,用以獲取無參的對象
@FunctionalInterface
private interface GetDog{
//若此方法僅僅是為了獲得一個Dog對象,而且通過無參構(gòu)造去獲取一個Dog對象作為返回值
Dog test();
}
//定義一個函數(shù)式接口,用以獲取有參的對象
@FunctionalInterface
private interface GetDogWithParameter{
//若此方法僅僅是為了獲得一個Dog對象,而且通過有參構(gòu)造去獲取一個Dog對象作為返回值
Dog test(String name,int age);
}
// 測試
public static void main(String[] args) {
//lambda表達(dá)式實現(xiàn)接口
GetDog lm = Dog::new; //引用到Dog類中的無參構(gòu)造方法,獲取到一個Dog對象
Dog dog = lm.test();
System.out.println("修狗的名字:"+dog.name+" 修狗的年齡:"+dog.age); //修狗的名字:null 修狗的年齡:0
GetDogWithParameter lm2 = Dog::new;//引用到Dog類中的有參構(gòu)造,來獲取一個Dog對象
Dog dog1 = lm2.test("薩摩耶",2);
System.out.println("修狗的名字:"+dog1.name+" 修狗的年齡:"+dog1.age);//修狗的名字:薩摩耶 修狗的年齡:2
}
}四、Lambda表達(dá)式需要注意的問題
這?類似于局部內(nèi)部類、匿名內(nèi)部類,依然存在閉包的問題。
如果在lambda表達(dá)式中,使用到了局部變量,那么這個局部變量會被隱式的聲明為 final。是?個常量,不能修改值。
總結(jié)
以上就是Lambda表達(dá)式相關(guān)內(nèi)容,本文僅簡單介紹了Lambda表達(dá)式的使用,祝各位小伙伴們學(xué)習(xí)愉快,歡迎交流!
到此這篇關(guān)于Java中Lambda表達(dá)式使用場景舉例的文章就介紹到這了,更多相關(guān)java lambda表達(dá)式使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring boot 集成 shiro 自定義密碼驗證 自定義freemarker標(biāo)簽根據(jù)權(quán)限渲染不同頁面(推薦
這篇文章主要介紹了spring-boot 集成 shiro 自定義密碼驗證 自定義freemarker標(biāo)簽根據(jù)權(quán)限渲染不同頁面,需要的朋友可以參考下2018-12-12
MybatisX-Generator不生成domain文件夾的問題及解決
在使用MybatisX-Generator生成數(shù)據(jù)庫表實體時,如果發(fā)現(xiàn)沒有生成domain文件夾以及User.java文件,是因為MybatisX版本更新,最新版需要在options里額外勾選model才能生成domain,勾選model并點擊finish后,成功生成domain文件夾及User.java文件2025-01-01
SpringBoot 項目中的圖片處理策略之本地存儲與路徑映射
在SpringBoot項目中,靜態(tài)資源存放在static目錄下,使得前端可以通過URL來訪問這些資源,我們就需要將文件系統(tǒng)的文件路徑與URL建立一個映射關(guān)系,把文件系統(tǒng)中的文件當(dāng)成我們的靜態(tài)資源即可,本文給大家介紹SpringBoot本地存儲與路徑映射的相關(guān)知識,感興趣的朋友一起看看吧2023-12-12
springmvc使用@notNull注解驗證請求參數(shù)方式
這篇文章主要介紹了springmvc使用@notNull注解驗證請求參數(shù)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教<BR>2024-01-01

