lambda表達式一篇就懂

一、概述

本文轉載 Lambda表達式一篇足夠,做了排版的優化,以及調整一些表達。最後給出了思考題的答案。

1、是什麼

Lambda表達式是一個匿名函數,即沒有函數名的函數。也可以理解成是一段可以傳遞的代碼(將代碼像數據一樣進行傳遞),這樣一來代碼更加簡潔。

2、爲什麼

  • 代碼簡潔
  • 可能還有一些優化,但是目前沒研究,研究到的時候再來補充。

二、語法組成

param -> body

  1. 中間以 -> 隔開形成左右兩部分。我們稱->爲箭頭操作符。
  2. 表達式左邊:Lambda表達式的參數列表。
  3. 表達式右邊:Lambda表達式中所需執行的功能,即Lambda體。

三、語法格式

1、無參無返回

方法沒參數且沒返回值,比如

public void test() {System.out.println("hello")}

用lambda表達式,首先看我們的Lambda組成公式:param -> body。無參就用()代替,那麼就是() -> body,方法體是輸出語句,所以:

() -> System.out.println("hello")

別問我方法名稱在哪?第一個就說了,匿名函數,即沒有函數名的函數。

2、一參無返回

方法有一個參數且沒返回值,比如:

public void test(int a) {System.out.println(a)}

用lambda表達式,首先看我們的Lambda組成公式:param -> body。有參數就放到()裏就行了,那麼就是

(int a) -> System.out.println(a)

值得注意的是:

  1. 若參數只有一個,則我們可以省略小括號,如下:int a -> System.out.println(a)
  2. 我們可以省略參數類型,因爲jdk會爲我們自動推斷。如下:a -> System.out.println(a)
3、多參無返回

方法有一個以上參數且沒返回值,比如:

public void test(int a, String b){System.out.println(a + ":" + b)}

用lambda表達式,首先看我們的Lambda組成公式:param -> body。有參數就放到()裏就行了,那麼就是

(int a, String b) -> {System.out.println(a + ":" + b)}

值得注意的是:

  1. 若參數只有一個,則我們可以省略小括號,但是一個以上就不能省略了。

  2. 我們可以省略參數類型,因爲jdk會爲我們自動推斷。如下:(a, b) -> {System.out.println(a + ":" + b)}

4、多參有返回

方法有一個以上參數且有返回值,比如:

public String test(int a, String b) {return a + ":" + b}

用lambda表達式,首先看我們的Lambda組成公式:param -> body。有參數就放到()裏就行了,那麼就是

(int a, String b) -> {return a + ":" + b}

值得注意的是:

  1. 若參數只有一個,則我們可以省略小括號,但是一個以上就不能省略了。
  2. 我們可以省略參數類型,因爲jdk會爲我們自動推斷。如下:(a, b) -> {return a + ":" + b}
5、體只有一條

首先看我們的Lambda組成公式:param -> body。體只有一條的意思是body只有一條語句,這種情況我們可以省略{},但多條語句的情況則不可省略。另外,單條語句有返回值的情況是可以省略return的。

比如:public void test(int a) {System.out.println(a)} 會寫成: a -> System.out.println(a)

比如:public int test(int a) {return a + 100} 會寫成: a -> a + 100

總結

普通 lambda寫法(最簡寫法) 備註
public void test() {System.out.println(“hello”)} () -> System.out.println(“hello”) 非最簡寫法的方法體可以帶花括號。如 () -> {...} 只有一條語句可省略
public void test(int a) {System.out.println(a)} a -> System.out.println(a) 支持 (int a) -> ...int a -> ... 的寫法,只有一個參數可以省略(),也可以省略參數類型
public void test(int a, String b) {System.out.println(a + “:” + b)} (a, b) -> System.out.println(a + “:” + b) 非一個參數就不能省略 ()
public String test(int a, String b) {return a + “:” + b} (a, b) -> a + “:” + b 也可以寫成 (a,b)->return a+":"+b,在單條語句的情況下,return可以省略

四、實戰演示

1、無參無返回
/**
 * 無參無返回,我們以Runnable接口爲例,因爲Runnable的run()方法就是無參無返回的。
 */
private static void test1() {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("test1");
        }
    };
    runnable.run();
}

public static void main(String[] args) {
    test1();
    /**
     * lambda的方式重寫無參無返回。
     * 說明一下:這裏的無參無返回指的是Runnable接口的run方法無參無返回,至於細節問題,先不管,下一章節你秒懂。
     * 現在你只需要知道lambda真的很簡單!
     */
    Runnable runnable = () -> System.out.println("test1");
    runnable.run();
}
2、一參無返回
/**
 * 一參無返回
 */
private static void test2(int a) {
    System.out.println("a=" + a);
}

public static void main(String[] args) {
    test2(1);
    /**
     * lambda的方式重寫一參無返回。
     * 說明一下:這裏的無參無返回指的是Consumer接口的accept方法一參無返回,你會問Consumer是什麼,先不管,下一章節你秒懂。
     * 現在你只需要知道lambda真的很簡單!
     */
    Consumer<Integer> consumer = (a) -> System.out.println("a=" + a);
    consumer.accept(1);
    //---------------------------一參可省略小括號-----------------------------------//
    Consumer<Integer> consumer2 = a -> System.out.println("a=" + a);
    consumer2.accept(1);
}
// 多參無返回同理,用BiConsumer,這裏不寫了。,直接搞多參有返回吧
3、多參有返回
public static void main(String[] args) {
    /**
     * 多參有返回,這裏拿比較接口來做案例
     */
    Comparator<Integer> comparator2 = new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            System.out.println("多參有返回");
            return Integer.compare(o1, o2);
        }
    };
    /**
     * lambda的方式重寫多參有返回。
     * 說明一下:這裏的多參無返回指的是Comparator接口的compare方法多參有返回,細節先不管,下一章節你秒懂。
     * 現在你只需要知道lambda真的很簡單!
     */
    Comparator<Integer> comparator = (a, b) -> {
        // 需要注意的是:body多行,{}不能省略。
        System.out.println("多參有返回");
        return a.compareTo(b);
    };
}

五、總結

本章要學會以下東西

  • 什麼是lambda
  • 爲什麼用lambda
  • lambda語法組成
  • lambda語法格式
  • 並不要求你會用
  • 要明白真的節省代碼,如下:對接口的創建匿名內部類的實現時,只需一句話,比如:
Runnable r = () -> System.out.println("hello");

而具體什麼樣的接口能用lambda呢?我們隨便寫個interface的話可以用嗎?顯然不行,這就引人深思了,爲什麼案例中的Runnable和Comparator接口都可以用lambda替代其內部類的實現?

(應該是隻有一個方法的接口才能用lambda,不然編譯器怎麼知道lambda的代碼片段實現接口的哪個方法呢?)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章