Lambda 表達式入門,看這篇就夠了

說出來怕大家不相信,剛接到物業通知,疫情防控升級了,車輛只能出不能進,每戶家庭天天可指派 1 名成員上街採購生活用品。這不是謠言,截個圖自證清白,出自洛陽市湖北路街道處。php

看來事態嚴峻,這樣看似好心,但不必定辦好事,去超時搶購的人會更多。無論了,只能窩在家作持久戰了。趁這段時間,多分享一些原創文章給大家——有眼福了呀,多儲備點知識,疫情結束後確定能派上大用場。今天分享的主題是《Lambda 表達式》,這也是以前一些讀者留言強烈要求我寫一寫的,很差意思,讓大家久等了,如今來知足大家,爲時不晚吧?java

0一、初識 Lambda

Lambda 表達式描述了一個代碼塊(或者叫匿名方法),能夠將其做爲參數傳遞給構造方法或者普通方法以便後續執行。考慮下面這段代碼:web

() -> System.out.println("沉默王二")
複製代碼

來從左到右解釋一下,() 爲 Lambda 表達式的參數列表(本例中沒有參數),-> 標識這串代碼爲 Lambda 表達式(也就是說,看到 -> 就知道這是 Lambda),System.out.println("沉默王二") 爲要執行的代碼,即將「沉默王二」打印到標準輸出流。express

有點 Java 基礎的同窗應該不會對 Runnable 接口感到陌生,這是多線程的一個基礎接口,它的定義以下:編程

@FunctionalInterface
public interface Runnable
{
   public abstract void run();
}
複製代碼

Runnable 接口很是簡單,僅有一個抽象方法 run();細心的同窗會發現一個陌生的註解 @FunctionalInterface,這個註解是什麼意思呢?數組

我看了它的源碼,裏面有這樣一段註釋:多線程

Note that instances of functional interfaces can be created with lambda expressions, method references, or constructor references.app

大體的意思就是說,經過 @FunctionalInterface 標記的接口能夠經過 Lambda 表達式建立實例。具體怎麼表現呢?ide

原來咱們建立一個線程並啓動它是這樣的:this

public class LamadaTest {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("沉默王二");
            }
        }).start();
    }
}
複製代碼

經過 Lambda 表達式呢?只須要下面這樣:

public class LamadaTest {
    public static void main(String[] args) {
        new Thread(() -> System.out.println("沉默王二")).start();
    }
}
複製代碼

是否是很妙!比起匿名內部類,Lambda 表達式不只易於理解,更大大簡化了必須編寫的代碼數量。

0二、Lambda 語法

每一個 Lambda 表達式都遵循如下法則:

( parameter-list ) -> { expression-or-statements }
複製代碼

() 中的 parameter-list 是以逗號分隔的參數。你能夠指定參數的類型,也能夠不指定(編譯器會根據上下文進行推斷)。Java 11 後,還可使用 var 關鍵字做爲參數類型,有點 JavaScript 的味道。

-> 至關於 Lambda 的標識符,就好像見到聖旨就見到了皇上。

{} 中的 expression-or-statements 爲 Lambda 的主體,能夠是一行語句,也能夠多行。

能夠經過 Lambda 表達式幹不少事情,好比說

1)爲變量賦值,示例以下:

Runnable r = () -> { System.out.println("沉默王二"); };
r.run();
複製代碼

2)做爲 return 結果,示例以下:

static FileFilter getFilter(String ext)
{
    return (pathname) -> pathname.toString().endsWith(ext);
}
複製代碼

3)做爲數組元素,示例以下:

final PathMatcher matchers[] =
{
        (path) -> path.toString().endsWith("txt"),
        (path) -> path.toString().endsWith("java")
};
複製代碼

4)做爲普通方法或者構造方法的參數,示例以下:

new Thread(() -> System.out.println("沉默王二")).start();
複製代碼

須要注意 Lambda 表達式的做用域範圍。

public static void main(String[] args) {

    int limit = 10;
    Runnable r = () -> {
        int limit = 5;
        for (int i = 0; i < limit; i++)
            System.out.println(i);
    };
}
複製代碼

上面這段代碼在編譯的時候會提示錯誤:變量 limit 已經定義過了。

和匿名內部類同樣,不要在 Lambda 表達式主體內對方法內的局部變量進行修改,不然編譯也不會經過:Lambda 表達式中使用的變量必須是 final 的。

0三、Lambda 和 this 關鍵字

Lambda 表達式並不會引入新的做用域,這一點和匿名內部類是不一樣的。也就是說,Lambda 表達式主體內使用的 this 關鍵字和其所在的類實例相同。

來看下面這個示例。

public class LamadaTest {
    public static void main(String[] args) {
        new LamadaTest().work();
    }

    public void work() {
        System.out.printf("this = %s%n"this);

        Runnable r = new Runnable()
        {
            @Override
            public void run()
            
{
                System.out.printf("this = %s%n"this);
            }
        };
        new Thread(r).start();
        new Thread(() -> System.out.printf("this = %s%n"this)).start();
    }
}
複製代碼

Tips:%s 表明當前位置輸出字符串,%n 表明換行符,也可使用 \n 代替,但 %n 是跨平臺的。

work() 方法中的代碼能夠分爲 3 個部分:

1)單獨的 this 關鍵字

System.out.printf("this = %s%n"this);
複製代碼

其中 this 爲 main() 方法中經過 new 關鍵字建立的 LamadaTest 對象——new LamadaTest()

2)匿名內部類中的 this 關鍵字

Runnable r = new Runnable()
{
    @Override
    public void run()
    
{
        System.out.printf("this = %s%n"this);
    }
};
複製代碼

其中 this 爲 work() 方法中經過 new 關鍵字建立的 Runnable 對象——new Runnable(){...}

3)Lambda 表達式中的 this 關鍵字

其中 this 關鍵字和 1)中的相同。

咱們來看一下程序的輸出結果:

this = com.cmower.java_demo.journal.LamadaTest@3feba861
this = com.cmower.java_demo.journal.LamadaTest$1@64f033cb
this = com.cmower.java_demo.journal.LamadaTest@3feba861
複製代碼

符合咱們分析的預期。

0四、最後

儘管 Lambda 表達式在簡化 Java 編程方面作了不少使人驚訝的努力,但在某些狀況下,不當的使用仍然會致使沒必要要的混亂,你們夥慎用。

好了,我親愛的讀者朋友們,以上就是本文的所有內容了。能在疫情期間堅持看技術文,二哥必需要伸出大拇指爲你點個贊👍,疫情事後,我相信你的才華必定會展露無疑。

原創不易,若是以爲有點用的話,請不要吝嗇你手中點贊的權力——由於這將是我寫做的最強動力。

相關文章
相關標籤/搜索