java8-Lambda表達式

Lambd

lambda表達式是java8的新特性,可以使用函數式介面替換掉原來的匿名內部類

lambda的本質就是引用一個已經具體實現的方法來完成對函數式介面抽象方法的具體實現

例如現在有一個介面,裡面只有一個求和方法

public interface Mylambda {
    int sum(int a,int b);
}

我們現在想要使用這個方法,有三種方式

  1. 創建一個類實現這個介面
  2. 匿名內部類
  3. 使用lambda函數式介面

第一種方法就不說了,來看使用匿名內部類

Mylambda myLambda=new Mylambda() {
    @Override
    public int sum(int a, int b) {
        return a+b;
    }
};

然後調用myLambda的sum方法可以做到求和的操作

再來看看lambda

Mylambda myLambda=(int a,int b)->{
    return a+b;
};

()->{} 什麼意思呢? 我們來看看lambda是如何使用的

() 裡面是傳入的參數

{} 裡面為方法體具體操作

需要注意的點

  1. lambda只能用於只有一個方法的介面
  2. 最好在介面上添加註解@FunctionalInterface來表明這是一個函數式介面
  3. 參數類型因為已經在介面中定義,那麼傳入參數時可以不用寫參數類型,要麼參數都寫參數類型,要不然都不寫參數類型
  4. 參數的數量,類型,順序必須和介面中一致

那麼lambda就這些嗎? 當然不是,還可以簡化以及拆分方法

簡化

如果方法體中就只有一條return語句,例如上面sum方法中,那麼在lambda表達式中可以省略大括弧以及return

public static void main(String[] args) {
    Mylambda mylambda = (a,b) -> a + b;
}

如果參數只有一個,可以省略小括弧

例如下面這個介面,我們並沒有做任何操作,只是將傳入參數原封不動返回,只是為了學習使用

@FunctionalInterface
public interface MyLambda2 {
    int print(int i);
}

使用

public static void main(String[] args) {
    MyLambda2 myLambda2= i -> i;
}

是不是看的有點蒙呢,不簡化就是

MyLambda2 myLambda2= (i) -> {
    return i;
};

因為參數只有一個,而且返回值也只有一條return語句,所以省略了傳入參數的小括弧以及方法體的大括弧和return關鍵字

這裡也有個需要注意的點 : 方法體的大括弧和return語句必須省略,不能只省略一個

如果方法中僅僅想返回一個對象,不做任何其他操作,還可以簡化

//介面============
@FunctionalInterface
public interface MyLambda2 {
    User getUser();
}
//使用,未簡化前===========
public static void main(String[] args) {
    MyLambda2 myLambda=()->{
        return  new User();
    };
}
//在根據參數和方法體簡化=====
public static void main(String[] args) {
    MyLambda2 myLambda2=()->new User();
}
//使用,簡化後
public static void main(String[] args) {
    MyLambda2 myLambda=User::new;
}

上面兩個簡化估計都可以看懂,但是最後一個User::new 估計有點蒙,什麼意思呢?

在開頭就講過 lambda的本質就是引用一個已經具體實現的方法來完成對函數式介面抽象方法的具體實現

而lambda創建User對象說白了就是調用User的構造方法,而lambda調用對象的構造方法的語法就是 類型::new也就是上面寫的User::new

那麼如果想通過lambda調用對象的有參構造呢?

很遺憾,不能通過這種方式來調用對象的有參構造,如果想通過lambda調用,我們可以稍微簡化為下面這種

//介面========
@FunctionalInterface
public interface MyLambda2 {
    User getUser(String name,int age);
}
//測試=============
public static void main(String[] args) {
    MyLambda2 myLambda2=(name,age)->new User();
}

拆分

那麼如果一個方法我們經常使用該怎麼辦呢,難道每次都去複製原來的lambda表達式嗎?

可以將常用的方法單獨拆分出來,每次lambda表達式去調用這個方法即可

我們以上面的sum介面為例 :

//介面===================
@FunctionalInterface
public interface Mylambda {
    int sum(int a,int b);
}
//測試==================
public static void main(String[] args) {
    Mylambda mylambda = (a,b)-> doSum(a,b);
    int sum = mylambda.sum(2, 5);
}
//抽取出的方法( 注意是靜態調用靜態,如果是普通方法需要創建對象 )===============
public static int doSum(int a,int b){
    return a+b;
}

我們將求和的操作單獨拆分為一個方法,每次使用時只需要調用這個方法即可

() -> xxx();

不僅可以直接寫方法具體細節,也可以調用其他方法,需要注意的時調用的方法返回值必須和介面定義返回值一致

本文僅個人理解,如果有不對的地方歡迎評論指出或私信,謝謝٩(๑>◡<๑)۶

Tags: