天天看點

最近學習到的Lambda表達式

前言

隻有光頭才能變強。
文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y

中秋去了躺上海,在外灘上打了個卡:

緊接着學了一下Java的函數式程式設計,給大家整理了一下,一起學習!

一、Lambda用法

之前寫Optional這個類的時候,簡單說了一下Lambda是怎麼用的,這裡再跟大家一起回顧一下,Lambda的文法是這樣的:

以Lambda文法建立線程和匿名内部類建立線程的差別(顯然代碼少了很多!):

public static void main(String[] args) {
    // 用匿名内部類的方式來建立線程
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("公衆号:Java3y---關注我!");
        }
    });

    // 使用Lambda來建立線程
    new Thread(() -> System.out.println("公衆号:Java3y---關注我!"));
}
           

使用Lambda表達式,實際就是建立出該接口的執行個體對象。

圖示;Runnable接口來舉例:

使用Labmda表達式需要函數式程式設計接口,比如在Runnable接口上我們可以看到

@FunctionalInterface

注解(标記着這個接口隻有一個抽象方法)

1.1 函數式程式設計接口

從上面的代碼例子可以看出,我們使用Lambda表達式建立線程的時候,并不關心接口名,方法名,參數名。我們隻關注他的參數類型,參數個數,傳回值。

JDK原生就給我們提供了一些函數式程式設計接口友善我們去使用,下面是一些常用的接口:

簡單說明一下:

  • 表格中的一進制接口表示隻有一個入參,二進制接口表示有兩個入參

Demo:

// Consumer 一個入參,無傳回值
Consumer<String> consumer = s-> System.out.println(s);
consumer.accept("Java3y");

// Supplier 無入參,有傳回值
Supplier<String> supplier = () -> "Java4y";
String s = supplier.get();
System.out.println(s);

//.....
           

使用Lambda時,要記住的就兩點:

  1. Lambda傳回的是接口的執行個體對象
  2. 有沒有參數、參數有多少個、需不需要有傳回值、傳回值的類型是什麼---->選擇自己合适的函數式接口

1.2 方法引用

在學Lambda的時候,還可能會發現一種比較奇怪的寫法,例如下面的代碼:

// 方法引用寫法
Consumer<String> consumer = System.out::println;
consumer.accept("Java3y");
           

如果按正常Lambda的寫法可能是這樣的:

// 普通的Lambda寫法
Consumer<String> consumer = s -> System.out.println(s);
consumer.accept("Java3y");
           

顯然使用方法引用比普通的Lambda表達式又簡潔了一些。

如果函數式接口的實作恰好可以通過調用一個方法來實作,那麼我們可以使用方法引用

方法引用又分了幾種:

  • 靜态方法的方法引用
  • 非靜态方法的方法引用
  • 構造函數的方法引用

方法引用Demo:

public class Demo {
    public static void main(String[] args) {
        // 靜态方法引用--通過類名調用
        Consumer<String> consumerStatic = Java3y::MyNameStatic;
        consumerStatic.accept("3y---static");

        //執行個體方法引用--通過執行個體調用
        Java3y java3y = new Java3y();
        Consumer<String> consumer = java3y::myName;
        consumer.accept("3y---instance");

        // 構造方法方法引用--無參數
        Supplier<Java3y> supplier = Java3y::new;
        System.out.println(supplier.get());
    }
}

class Java3y {
    // 靜态方法
    public static void MyNameStatic(String name) {
        System.out.println(name);
    }

    // 執行個體方法
    public void myName(String name) {
        System.out.println(name);
    }

    // 無參構造方法
    public Java3y() {
    }
}
           

結果如下:

最後

Lambda雖然代碼看起來是簡潔,但是如果複雜的話還是比較難看明白的。

在學習Lambda的時候,首先我們得知道有哪些常用函數式程式設計接口,這些函數式程式設計接口的有什麼差別(參數個數、傳回值類型)

Lambda表達式傳回的是接口對象執行個體,如果函數式接口的實作恰好可以通過調用一個方法來實作,那麼我們可以使用方法引用來替代Lambda表達式

最後再完整舉個例子:

// Supplier是一個無入參帶傳回的值的函數式程式設計接口

// () -> new Java3y()這整句Lambda表達式,傳回的是Supplier接口的執行個體。從Lambda表達式可以看出無參數,帶傳回值
Supplier<Java3y> supplier = () -> new Java3y(); 

// 由于這個“() -> new Java3y()”Lambda表達式可以通過調用一個方法就實作了,那麼我們可以優化成方法引用
Supplier<Java3y> supplier2 = Java3y::new;

           
樂于輸出幹貨的Java技術公衆号:Java3y。公衆号内有200多篇原創技術文章、海量視訊資源、精美腦圖,關注即可擷取!

覺得我的文章寫得不錯,點贊!

更多的文章可往:文章的目錄導航