天天看點

Java 8 - Lambda表達式

在Java 8中,為了能夠将行為參數化而引入了Lambda表達式。

可以把Lambda表達式了解為簡潔地表示可傳遞的匿名函數的一種方式:它沒有名稱,但它有參數清單、函數主體、傳回類型,可能還有一個可以抛出的異常清單。

文法

Lambda表達式在Java語言中引入了

->

操作符,

->

操作符被稱為Lambda表達式的操作符或者箭頭操作符,它将Lambda表達式分為兩部分:

  • 左側部分指定了Lambda表達式需要的所有參數,Lambda表達式本質上是對接口的實作,Lambda表達式的參數清單本質上對應着接口中方法的參數清單。
  • 右側部分指定了Lambda體,即Lambda表達式要執行的功能,Lambda體本質上就是接口方法具體實作的功能。

Lambda表達式的參數清單的資料類型可以省略不寫,因為JVM編譯器能夠通過上下文推斷出資料類型,這就是

類型推斷

  • 左側部分隻有一個參數時,小括号可以省略
  • Lambda表達式的參數清單的資料類型可以省略不寫,因為JVM編譯器能夠通過上下文推斷出資料類型,這就是“類型推斷”
public class LambdaTest {
    public void completedLeft() {
        // 類型String可以省略,由上下文進行類型推斷;因為隻有一個參數,小括号可以省略
        Consumer<String> consumer = (String e) -> println(e.substring(3, 6));
    }
    
    public void singleLeft() {
        Consumer<String> consumer = e -> println(e.substring(3, 6));
    }
}
           
  • 右側部分隻有一行語句時,大括号和

    return

    關鍵字可以省略
public class LambdaTest {
    public String completeRight() {
        Supplier<String> supplier = () -> {
            String result = new Random().nextInt(100) + "";
            return result.substring(1);
        };
        return supplier.get();
    }

    public String simpleRight() {
        Supplier<String> supplier = () -> new Random().nextInt(100) + "";
        return supplier.get();
    }
}
           
  • 無參無傳回值
public interface INoArgsAndNoReturn {
    void execute();
}
           
public class LambdaTest {
    public void noArgsAndNoReturn() {
        INoArgsAndNoReturn lambda = () -> println("execute lambda");
        execute(lambda);
    }

    private void execute(INoArgsAndNoReturn lambda) {
        lambda.execute();
    }
}
           
  • 無參有傳回值
public interface INoArgsAndHasReturn {
    String execute();
}
           
public class LambdaTest {
    public void noArgsAndHasReturn() {
        INoArgsAndHasReturn lambda = () -> "return lambda result";
        execute(lambda);
    }

    private void execute(INoArgsAndHasReturn lambda) {
        println(lambda.execute());
    }
}
           
  • 有參無傳回值
public interface IHasArgsAndNoReturn {
    void execute(Integer one, Integer two);
}
           
public class LambdaTest {
    public void hasArgsAndNoReturn() {
        IHasArgsAndNoReturn lambda = (a, b) -> println(a + b);
        execute(lambda);
    }

    private void execute(IHasArgsAndNoReturn lambda) {
        lambda.execute(1, 2);
    }
}
           
  • 有參有傳回值
public interface IHasArgsAndHasReturn {
    String execute(Integer one, Integer two);
}
           
public class LambdaTest {
    public void hasArgsAndHasReturn() {
        execute((x, y) -> x + " " + y);
    }

    private void execute(IHasArgsAndHasReturn argsReturn) {
        println(argsReturn.execute(1, 2));
    }
}
           

使用局部變量

對局部變量的限制

經驗總結

  • lambda表達式通過傳遞代碼,來使代碼根據條件被延遲執行或不執行。
  • 多參數lambda通過建立比對的函數式接口來實作。

繼續閱讀