App下載

Java8新特性之Lambda的詳細(xì)內(nèi)容匯總

猿友 2021-08-03 12:00:13 瀏覽數(shù) (2296)
反饋

1. lambda表達(dá)式介紹

lambda表達(dá)式是Java8提供的新特性之一,也可以稱之為閉包;它支持Java能夠進(jìn)行簡(jiǎn)單的函數(shù)式編程,也就是說(shuō)可以把一個(gè)匿名函數(shù)作為一個(gè)方法的參數(shù)進(jìn)行傳遞;其格式分為三部分,第一部分為入?yún)⒘斜?,第二部?code>->固定組成,第三部分為方法體;

public class LambdaTest {

    public static void main(String[] args) {
        // 使用lambda表達(dá)式創(chuàng)建線程
        Thread thread = new Thread(() -> {
            System.out.println("thread running");
        });
        thread.start();
    }
}

// 運(yùn)行結(jié)果
thread running

2. lambda表達(dá)式的重要特征

可選的參數(shù)類型聲明:不需要聲明參數(shù)的類型,編譯器可以統(tǒng)一識(shí)別參數(shù)值;

public class LambdaTest {

    private Integer a;

    public LambdaTest(Integer a) {
        this.a = a;
    }

    public void print(LambdaInterface lambdaInterface) {
        lambdaInterface.print(this.a);
    }

    public static void main(String[] args) {
        LambdaTest lambdaTest = new LambdaTest(123);
        // 聲明參數(shù)類型
        System.out.println("聲明參數(shù)類型");
        lambdaTest.print((Integer a) -> {
            System.out.println("a: " + a);
        });
        // 不聲明參數(shù)類型
        System.out.println("不聲明參數(shù)類型");
        lambdaTest.print((a) -> {
            System.out.println("a: " + a);
        });
    }
}

interface LambdaInterface {
    void print(Integer a);
}

// 運(yùn)行結(jié)果
聲明參數(shù)類型
a: 123
不聲明參數(shù)類型
a: 123

可選的參數(shù)圓括號(hào):一個(gè)參數(shù)時(shí)不需要定義圓括號(hào),但沒(méi)有參數(shù)或者多個(gè)參數(shù)時(shí)則必須要定義;

public class LambdaTest {

    private Integer a;

    public LambdaTest(Integer a) {
        this.a = a;
    }

    public void print(LambdaInterface lambdaInterface) {
        lambdaInterface.print(this.a);
    }

    public static void main(String[] args) {
        LambdaTest lambdaTest = new LambdaTest(123);
        // 定義參數(shù)圓括號(hào)
        System.out.println("定義參數(shù)圓括號(hào)");
        lambdaTest.print((a) -> {
            System.out.println("a: " + a);
        });
        // 一個(gè)參數(shù)可不定義參數(shù)圓括號(hào)
        System.out.println("一個(gè)參數(shù)可不定義參數(shù)圓括號(hào)");
        lambdaTest.print(a -> {
            System.out.println("a: " + a);
        });
    }
}

interface LambdaInterface {
    void print(Integer a);
}

// 運(yùn)行結(jié)果
定義參數(shù)圓括號(hào)
a: 123
一個(gè)參數(shù)可不定義參數(shù)圓括號(hào)
a: 123

可選的大括號(hào):如果方法體僅有一個(gè)語(yǔ)句,可不需要使用大括號(hào);

public class LambdaTest {

    private Integer a;

    public LambdaTest(Integer a) {
        this.a = a;
    }

    public void print(LambdaInterface lambdaInterface) {
        lambdaInterface.print(this.a);
    }

    public static void main(String[] args) {
        LambdaTest lambdaTest = new LambdaTest(123);
        // 使用方法體大括號(hào)
        System.out.println("使用方法體大括號(hào)");
        lambdaTest.print(a -> {
            System.out.println("a: " + a);
        });
        // 一個(gè)語(yǔ)句可不使用方法體大括號(hào)
        System.out.println("一個(gè)語(yǔ)句可不使用方法體大括號(hào)");
        lambdaTest.print(a -> System.out.println("a: " + a));
    }
}

interface LambdaInterface {
    void print(Integer a);
}

// 運(yùn)行結(jié)果
使用方法體大括號(hào)
a: 123
一個(gè)語(yǔ)句可不使用方法體大括號(hào)
a: 123

可選的返回關(guān)鍵字:如果方法體僅有一個(gè)表達(dá)式返回值語(yǔ)句,可不需要聲明返回關(guān)鍵字,但存在大括號(hào)時(shí)則必須聲明;

public class LambdaTest {

    private Integer a;
    private Integer b;

    public LambdaTest(Integer a, Integer b) {
        this.a = a;
        this.b = b;
    }

    public Integer sum(LambdaInterface lambdaInterface) {
        return lambdaInterface.calculate(this.a, this.b);
    }

    public static void main(String[] args) {
        LambdaTest lambdaTest = new LambdaTest(123, 456);
        // 聲明返回關(guān)鍵字
        System.out.println("聲明返回關(guān)鍵字");
        Integer s1 = lambdaTest.sum((Integer a, Integer b) -> {
            return a + b;
        });
        System.out.println(s1);
        // 一個(gè)表達(dá)式返回值語(yǔ)句可不聲明返回關(guān)鍵字
        System.out.println("一個(gè)表達(dá)式返回值語(yǔ)句可不聲明返回關(guān)鍵字");
        Integer s2 = lambdaTest.sum((a, b) -> a + b);
        System.out.println(s2);
    }
}

interface LambdaInterface {
    Integer calculate(Integer a, Integer b);
}

// 運(yùn)行結(jié)果
聲明返回關(guān)鍵字
579
一個(gè)表達(dá)式返回值語(yǔ)句可不聲明返回關(guān)鍵字
579

3. lambda表達(dá)式對(duì)域外變量的限制

lambda表達(dá)式對(duì)域外的局部變量具有隱性final語(yǔ)義的限制,但對(duì)成員變量沒(méi)有該限制;

public class LambdaTest {

    private Integer a;
    private Integer b;

    public LambdaTest(Integer a, Integer b) {
        this.a = a;
        this.b = b;
    }

    public Integer sum(LambdaInterface lambdaInterface) {
        return lambdaInterface.calculate(this.a, this.b);
    }

    public static void main(String[] args) {
        LambdaTest lambdaTest = new LambdaTest(123, 456);
        int c = 111;
        Integer s1 = lambdaTest.sum((a, b) -> {
            // 修改域外局部變量將出現(xiàn)編譯錯(cuò)誤
            c = 222;
            return a + b;
        });
        System.out.println(s1);

        int d = 333;
        Integer s2 = lambdaTest.sum((a, b) -> {
            // 域外修改lambda表達(dá)式內(nèi)部使用過(guò)的域外局部變量也將導(dǎo)致編譯錯(cuò)誤
            return a + b + d;
        });
        d = 444;
        System.out.println(s2);
    }
}

interface LambdaInterface {
    Integer calculate(Integer a, Integer b);
}
public class LambdaTest {

    private Integer a;
    private Integer b;
    private Integer c;

    public LambdaTest(Integer a, Integer b, Integer c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public Integer sum(LambdaInterface lambdaInterface) {
        return lambdaInterface.calculate(this.a, this.b);
    }

    public static void main(String[] args) {
        LambdaTest lambdaTest = new LambdaTest(123, 456, 789);
        Integer s1 = lambdaTest.sum((a, b) -> {
            // 沒(méi)有出現(xiàn)編譯錯(cuò)誤
            lambdaTest.c = 999;
            return a + b + lambdaTest.c;
        });
        System.out.println(s1);
    }
}

interface LambdaInterface {
    Integer calculate(Integer a, Integer b);
}

// 運(yùn)行結(jié)果
1578

4. lambda表達(dá)式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

1.使代碼更加簡(jiǎn)潔;

2.減少匿名內(nèi)部類的創(chuàng)建,節(jié)省資源;

缺點(diǎn):

1.可維護(hù)性差,必須熟悉抽象方法的參數(shù)列表;

2.可讀性差,必須對(duì)lambda表達(dá)式有一定深入;

5. lambda表達(dá)式的使用場(chǎng)景

在聲明方法時(shí),方法的形參列表包含一個(gè)或者多個(gè)函數(shù)式接口就可以使用lambda表達(dá)式;如:

使用實(shí)現(xiàn)Runnable接口創(chuàng)建線程

使用實(shí)現(xiàn)Callable接口創(chuàng)建FutureTask

使用四大函數(shù)式接口消費(fèi)者接口Consumer提供者接口Supplier、斷言型接口Predicate函數(shù)型接口Function


6. lambda表達(dá)式的實(shí)現(xiàn)原理

lambda表達(dá)式是通過(guò)特定的語(yǔ)法,讓編譯器對(duì)java文件進(jìn)行編譯時(shí),針對(duì)每一個(gè)lambda表達(dá)式會(huì)編譯成一個(gè)對(duì)應(yīng)的靜態(tài)方法,由此也可證明lambda表達(dá)式并不是一種語(yǔ)法糖;

// 對(duì)上面的LambdaTest.java編譯后的LambdaTest.class文件使用javap -p進(jìn)行查看將會(huì)得到如下結(jié)果
javap -p LambdaTest.class
Compiled from "LambdaTest.java"
public class cn.jackiegu.java8.study.lambda.LambdaTest {
  private java.lang.Integer a;
  private java.lang.Integer b;
  private java.lang.Integer c;
  public cn.jackiegu.java8.study.lambda.LambdaTest(java.lang.Integer, java.lang.Integer, java.lang.Integer);
  public java.lang.Integer sum(cn.jackiegu.java8.study.lambda.LambdaInterface);
  public static void main(java.lang.String[]);
  private static java.lang.Integer lambda$main$0(cn.jackiegu.java8.study.lambda.LambdaTest, java.lang.Integer, java.lang.Integer);
}

到此這篇關(guān)于 Java 8 新特性 lambda 表達(dá)式詳細(xì)內(nèi)容總結(jié)的文章就介紹到這了,想要了解更多相關(guān) Java 其他新特性的內(nèi)容請(qǐng)搜索W3Cschool以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,也希望大家以后多多支持!


0 人點(diǎn)贊