Java8中Lambda表達式詳解


對於任何場景而言,代碼量永遠都是越少越好,而Java8中提供的Lambda表達式正式簡化代碼的利器。
參考博客:Java 8 Lambda 表達式詳解
參考博客:完美的lambda表達式只有一行

在 Java 8 以前,若我們想要把某些功能傳遞給某些方法,總要去寫匿名類

manager.addScheduleListener(new ScheduleListener() {
    @Override
    public void onSchedule(ScheduleEvent e) {        
        // Event listener implementation goes here...
    }
});

Java 是面向對象語言,除了原始數據類型之處,Java 中的所有內容都是一個對象。而在函數式語言中,我們只需要給函數分配變量,並將這個函數作為參數傳遞給其它函數就可實現特定的功能。JavaScript 就是功能編程語言的典范(閉包)。也就是說Java中方法參數只有兩種:一是基礎數據類型,一是對象。為了兼容函數式編程,而出現了Lambda表達式。

什么是Lambda表達式

Java 中的 Lambda 表達式通常使用語法是 (argument) -> (body),比如:

(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }

如果Lambda表達式只有一行,則不需要{}return、或者;,比如:

(Integer e)  -> e*2

再比如Lambda要創建一個比較器:

Comparator c = (p1, p2) -> p1.getAge().compareTo(p2.getAge());

甚至於:

Comparator c = Comparator.comparing(Person::getAge);

在這里的::就是Java中的方法引用。

功能接口

在 Java 中,功能接口(Functional interface)指只有一個抽象方法的接口。
每個 Lambda 表達式都可以隱式地分配給功能接口。例如,我們可以從 Lambda 表達式創建 Runnable 接口的引用,如下所示:

Runnable r = () -> System.out.println("hello world");

編譯器會自動將上面的代碼編譯為:

new Thread(
    () -> System.out.println("hello world")
).start();

Lambda 表達式的例子

線程初始化

// Old way
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello world");
    }
}).start();

// New way
new Thread(
    () -> System.out.println("Hello world")
).start();

事件處理

// Old way
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Hello world");
    }
});

// New way
button.addActionListener( (e) -> {
        System.out.println("Hello world");
});

遍例輸出(方法引用)

// old way
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
for (Integer n : list) {
    System.out.println(n);
}

// 使用 -> 的 Lambda 表達式
list.forEach(n -> System.out.println(n));

// 使用 :: 的 Lambda 表達式
list.forEach(System.out::println);

邏輯操作

package com.wuxianjiezh.demo.lambda;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Main {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

        System.out.print("輸出所有數字:");
        evaluate(list, (n) -> true);

        System.out.print("不輸出:");
        evaluate(list, (n) -> false);

        System.out.print("輸出偶數:");
        evaluate(list, (n) -> n % 2 == 0);

        System.out.print("輸出奇數:");
        evaluate(list, (n) -> n % 2 == 1);

        System.out.print("輸出大於 5 的數字:");
        evaluate(list, (n) -> n > 5);
    }

    public static void evaluate(List<Integer> list, Predicate<Integer> predicate) {
        for (Integer n : list) {
            if (predicate.test(n)) {
                System.out.print(n + " ");
            }
        }
        System.out.println();
    }
}

Stream API 示例

// old way
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
for(Integer n : list) {
    int x = n * n;
    System.out.println(x);
}

// new way
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
list.stream().map((x) -> x*x).forEach(System.out::println);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM