Java的Lambda表達(dá)式

Java的Lambda表達(dá)式

1. 什么是Lambda表達(dá)式

簡單的說,Lambda表達(dá)式就是匿名方法。Lambda表達(dá)式讓程序員能夠使用更加簡潔的代碼,但是同樣也使代碼的可讀性比較差。

Lambda表達(dá)式也叫做匿名方法或者閉包。

2. 和匿名內(nèi)部類做對比

Lambda是匿名方法,這個時候我們會想想到匿名內(nèi)部類,我們來回想一下匿名內(nèi)部類的用法,比如下面的代碼就是使用匿名內(nèi)部類實(shí)現(xiàn)了一個線程。

public class Test {
  public static void main(String[] args) {
    Thread t = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("線程:" + Thread.currentThread().getName());
      }
    });
    t.start();
  }
}

我們一般的做法是寫一個Runnable接口的實(shí)現(xiàn)類,然后new一個實(shí)現(xiàn)類再傳給Thread的構(gòu)造器。如下:

public class Test {

  public static void main(String[] args) {
    MyThread myThread = new MyThread();
    Thread t = new Thread(myThread);
    t.start();
  }

  static class MyThread implements Runnable {
    @Override
    public void run() {
      System.out.println("線程:" + Thread.currentThread().getName());
    }
  }
  
}

可以看到使用匿名內(nèi)部類的話就省略了新建Runnable接口的實(shí)現(xiàn)類這一步驟。

3. 使用Lambda表達(dá)式

上面使用匿名內(nèi)部類的寫法,如果使用Lambda表達(dá)式可以寫成下面這樣:

public class Test {
  public static void main(String[] args) {
    Thread t = new Thread(() ->  {
      System.out.println("線程:" + Thread.currentThread().getName());
    });
    t.start();
  }
}

這樣有一個問題,如果接口里面有多個方法,那么Lambda表達(dá)式怎么知道實(shí)現(xiàn)的是哪個方法呢?我們通過代碼測試一下:

package com.wangjun.othersOfJava;

public class LambdaTest {

    public static void main(String[] args) {
        Animal a = () -> {  // 編譯報(bào)錯:The target type of this expression must be a functional interface
            System.out.println("狗狗吃飯");
        };
        a.eat();
    }
    interface Animal {
        public void eat();
        public void duty();
    }
}

可以看到編譯報(bào)錯,這個提到一個functional interface,就是函數(shù)式接口。函數(shù)式接口就是只有一個抽象方法的接口。這樣,就不難理解了,原來Lambda表達(dá)式只支持函數(shù)式接口。

4. Lambda表達(dá)式使用的幾種方式

package com.wangjun.othersOfJava;

public class LambdaTest {
    
    public static void main(String[] args) {
        
        // 帶類型
        Animal a1 = (String str) -> {
            System.out.println("狗狗吃飯:" + str);
        };
        // 不帶類型
        Animal a2 = (str) -> {
            System.out.println("狗狗吃飯:" + str);
        };
        // 不帶括號
        Animal a3 = str -> {
            System.out.println("狗狗吃飯:" + str);
        };
        // 不帶大括號
        Animal a4 = str -> System.out.println("狗狗吃飯:" + str);
        a1.eat("火腿腸");
        a2.eat("牛肉");
        a3.eat("面條");
        a4.eat("米飯");
        
        // 使用return返回
        Person p1 = () -> {
            return "老師的職責(zé):教書育人!";
        };
        // 直接返回
        Person p2 = () -> "醫(yī)生的職責(zé):救死扶傷!";
        System.out.println(p1.duty());
        System.out.println(p2.duty());
    }
    
    // 沒有返回值
    interface Animal {
        public void eat(String str);
    }
    // 有返回值
    interface Person {
        public String duty();
    }
}

4. Java的雙冒號表達(dá)式

JDK8中有雙冒號的用法,就是把方法當(dāng)做參數(shù)傳到stream內(nèi)部,使stream的每個元素都傳入到該方法里面執(zhí)行一下。下面通過遍歷一個List來說明一下雙冒號和Lambda表達(dá)式使用方式的不同。

package com.wangjun.othersOfJava;

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

public class LambdaTest {
    
  public static void printStr(String str) {
    System.out.println(str);
  }

  public static void main(String[] args) {

    List<String> list = Arrays.asList("aaa","bbb","ccc");
    // 1.通常的遍歷方式
    for(String str: list) {
      LambdaTest.printStr(str);
    }
    // 2.使用Lambda表達(dá)式遍歷
    list.forEach(str -> {
      LambdaTest.printStr(str);
    });
    // 3.使用::遍歷
    list.forEach(LambdaTest::printStr);
    // 下面的方法和上面等價(jià),使用的是函數(shù)式編程
    Consumer<String> methodParam = LambdaTest::printStr; //方法參數(shù)
    list.forEach(x -> methodParam.accept(x));//方法執(zhí)行accept
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容