Java8中的Lambda表達式理解與使用示例詳解
一、什么是Lambda表達式
Lambda表達式是Java 8引入的一個特性,它允許你以匿名函數(shù)的方式寫出更簡潔的代碼,所以說,也可以理解為它和特定匿名函數(shù)是一個意思,只是寫法上不同,更加的簡潔(當然看不習慣的反而可能覺得復雜)。
Lambda表達式的基本語法是 (parameters) -> expression,其中 -> 表示將參數(shù)映射到表達式上。
Lambda表達式可以用于實現(xiàn)函數(shù)式接口,即只包含一個抽象方法的接口。
上面紅色字體說明了Lambda表達式與普通匿名函數(shù)的區(qū)別,它所需要的條件比較嚴格,并不適合簡化所有的匿名函數(shù)。
二、Lambda表達式和匿名函數(shù)的差別
上面已經(jīng)說明了Lambda表達式和匿名函數(shù)一樣,都可以實現(xiàn)函數(shù)式接口,但只能是包含唯一一個抽象方法的,并且是接口interface類。
public class LambdaTest {
public static void main(String[] args) {
checkId1("1", User::getUserIdStatic); //使用引用類靜態(tài)方法,得到的id與User類靜態(tài)值有關
User user = new User("2");
checkId1("1", user::getUserId); //使用引用實例對象方法,得到的id與user實例有關
checkId1("1", ()-> user.getUserId()); //使用正常Lambda表達式(簡化了{}和return),->后加上{}可以正常編寫方法實現(xiàn)內(nèi)容
checkId2("1", new ICommonFun(){ //使用匿名函數(shù),因為這個接口的抽象方法數(shù)量大于1個
@Override
public String getId() {
return user.getUserId();
}
@Override
public void setId(String id) {
}
});
}
public static void checkId1(String id, ILambdaFun iLambdaFun){
if (id.equals(iLambdaFun.getId())){
System.out.println("id相等");
}else{
System.out.println("id不相等");
}
}
public static void checkId2(String id, ICommonFun iCommonFun){
if (id.equals(iCommonFun.getId())){
System.out.println("id相等");
}else{
System.out.println("id不相等");
}
}
interface ILambdaFun {
String getId(); // 方法參數(shù)數(shù)量為0個,所以lambda表達式為()->{}
}
interface ICommonFun {
String getId();
void setId(String id); //多了這個方法,所以無法使用Lambda表達式來實現(xiàn)這個接口。去掉或改為非抽象方法才可以使用Lambda表達式來實現(xiàn)這個接口。
}
static class User {
private String id;
private static String idStatic = "1";
User(String id){
this.id = id;
}
private String getUserId () {
return id;
}
private static String getUserIdStatic () {
return idStatic;
}
}
}
// 運行結果
//id相等
//id不相等
//id不相等
//id不相等三、Lambda表達式的4種方法引用
上面的代碼例子中,在使用Lambda表達式時,使用了2種方法引用,和Lambda正常表達式。Lambda表達式總共有4種方法引用:
1,靜態(tài)方法引用(上面代碼例子有使用過)
2,實例方法引用(上面代碼例子有使用過)
3,構造方法引用
4,特殊方法引用
第一種:靜態(tài)方法引用
引用語法:類名::方法名,如User::getIdStatic()
注意事項:
函數(shù)式接口(interface類)中抽象方法參數(shù)列表是什么樣的,被引用的方法參數(shù)列表也要是一樣的;
接口的抽象方法沒有返回值,被引用的方法返回值可有可無;
接口的抽象方法有返回值,被引用的方法必須有相同類型的返回值。
第二種:實例方法引用
引用語法:對象名::非靜態(tài)方法名,如:user::getId()
注意事項:
函數(shù)式接口(interface類)中抽象方法參數(shù)列表是什么樣的,被引用的方法參數(shù)列表也要是一樣的;
接口的抽象方法沒有返回值,被引用的方法返回值可有可無;
接口的抽象方法有返回值,引用的方法必須有相同類型的返回值。
第三種:構造方法引用
引用語法:類名::new,如:String::new
注意事項:
函數(shù)式接口(interface類)中抽象方法參數(shù)列表是什么樣的,被引用的構造方法參數(shù)列表也要是一樣的。
第四種:特殊方法引用
引用語法:類名::實例方法名,如User::getId()
注意事項:
在抽象方法中,第一個參數(shù)可以作為被引用的實例方法(如getId())的調(diào)用者(如User實例對象),就可以簡化。所以這種抽象方法必須有至少一個參數(shù),且第一個參數(shù)是可以調(diào)用實例方法的對象;除去第一個參數(shù)的其余參數(shù)組成的參數(shù)列表,在第一個參數(shù)代表的對象類里,必須有對應的非靜態(tài)實例方法。(如,抽象方法為void setObject(User user,String v1),則User類里必須有fun(String v1)方法,方法返回值同第一二種要求。)
public class LambdaTest {
public static void main(String[] args) {
checkId1("1", User::getUserId); // 看著像引用靜態(tài)方法
}
public static void checkId1(String id, ILambdaFun iLambdaFun){
if (id.equals(iLambdaFun.getObject(new User("1")))){ // 使用函數(shù)實例的抽象方法時,需要根據(jù)參數(shù)傳入實例對象
System.out.println("id相等");
}else{
System.out.println("id不相等");
}
}
interface ILambdaFun {
Object getObject(User user); // 抽象方法里有且只有一個參數(shù)
}
static class User {
private String id;
private static String idStatic = "1";
User(String id){
this.id = id;
}
private String getUserId () {
return id;
}
private static String getUserIdStatic () {
return idStatic;
}
}
}四、拓展
Java中一些可使用Lambda表達式的接口
Consumer<T>:接受一個輸入?yún)?shù)并不返回結果。Supplier<T>:不接受任何參數(shù),返回一個結果。Function<T, R>:接受一個參數(shù)并返回一個結果。Predicate<T>:接受一個參數(shù),返回一個布爾值。
public class LambdaTest {
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
User user1 = new User("1");
userList.add(user1);
userList.add(new User("2"));
HashMap<String,User> map = listToMap(userList, User::getUserId); //需要其它屬性值作為Map的Key,直接換一個引用方法即可
System.out.println(map.get("1"));
System.out.println(map.get("2"));
}
public static HashMap<String, User> listToMap(List<User> userList, Function<User, String> function){
HashMap<String, User> userMap = new HashMap<>();
userList.forEach((item)->{
userMap.put(function.apply(item), item);
});
return userMap;
}
public static class User {
private String id;
private static String idStatic = "1";
User(String id){
this.id = id;
}
private String getUserId () {
return id;
}
private static String getUserIdStatic () {
return idStatic;
}
@Override
public String toString() {
return "User{id:"+id+"}";
}
}
}
// 運行結果
//User{id:1}
//User{id:2}到此這篇關于Java8中的Lambda表達式理解與使用的文章就介紹到這了,更多相關Java8 Lambda表達式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot使用Spring Test進行集成測試的流程步驟
Spring Test 是 Spring Framework 提供的一個測試框架,它可以幫助我們進行集成測試,在本文中,我們將介紹如何使用 Spring Test 進行集成測試,需要的朋友可以參考下2023-06-06
IntelliJ IDEA 2023.2正式發(fā)布新UI和Profiler轉(zhuǎn)正(最新推薦)
北京時間2023年7月26日,IntelliJ IDEA 2023.2正式發(fā)布,IntelliJ IDEA 2023.2 引入 AI Assistant(AI助手),通過一組由 AI 提供支持的功能助力開發(fā),今天給大家分享IntelliJ IDEA 2023.2正式發(fā)布新UI和Profiler轉(zhuǎn)正,感興趣的朋友一起看看吧2023-10-10

