1. 程式人生 > 程式設計 >一文帶你徹底搞懂Lambda表示式

一文帶你徹底搞懂Lambda表示式

1. 為什麼使用Lambda表示式

Lambda是一個匿名函式,我們可以把Lambda表示式理解為是一段可以傳遞的程式碼(將程式碼像資料一樣進行傳遞)。可以寫出更簡潔、更靈活的程式碼。作為一種更緊湊的程式碼風格,使Java的語言表達能力得到了提升。

我們來看一下使用lambda之前建立匿名內部類:

new Thread(new Runnable() {
  @Override
  public void run() {
    System.out.println("執行Runnable方法");
  }
});

lambda表示式:

new Thread(() -> System.out.println("執行Runnable方法")); // 無參Lambda表示式

在Idea中遇到可以轉換lambda的程式碼會有灰色提示,按alt+enter可自動轉換:

一文帶你徹底搞懂Lambda表示式

2. Lambda語法

Java8中引入了一個新的操作符"->”該操作符稱為箭頭操作符或Lambda 操作符。

箭頭操作符將Lambda表示式拆分成兩部分:

左側: Lambda表示式的引數列表

右側: Lambda表示式中所需執行的功能,即Lambda體

示例:

語法格式一:無引數,無返回值。

Runnable r = () -> System.out.println("Hello World");

r.run();

語法格式二:有一個引數,並且無返回值。

Consumer consumer = (x) -> System.out.println(x);
//或者寫成: x -> System. out.println(x); 只有一個引數,括號可以省略
consumer.accept("Hello");

語法格式三:有兩個以上的引數,有返回值,並且Lambda體中有多條語句。

Comparator<Integer> comparator = (x,y) -> {
  System.out.println("Hello");
  return Integer.compare(x,y);
};
TreeSet<Integer> treeSet = new TreeSet<>(comparator);

語法格式四:若Lambda體中只有一條語句,return 和大括號都可以省略不寫,Lambda 表示式的引數列表的資料型別可以省略不寫,因為JVM編譯器通過上下文推斷出資料型別,即型別推斷

Comparator<Integer> com = (x,y) -> Integer .compare(x,y);

關於型別推斷,其實在陣列中我們早已經使用過:

String[] strArr = {"a","b","c"}; // 型別推斷
// 寫成下面這種方式則編譯報錯
String [] strArr;
strArr = {"a","c"}; 
// 還有List的型別推斷:
List<String> list = new ArrayList<>(); 

3. 函數語言程式設計介面

上面我們看到的lambda表示式,其實都依賴於介面的支援,lambda表示式的本質是對介面的一種實現。這種介面稱為函式式介面,即介面中只有一個抽象方法的介面。函式式介面可以使用@FunctionInterface註解修飾,表示被修飾的介面必須是函式式介面。

// 函式式介面只能有一個抽象方法
@FunctionalInterface
public interface FuncTest {
  void accept(Object o);
}

如果在函式式介面中寫兩個以上的方法,編譯會報錯:

一文帶你徹底搞懂Lambda表示式

我們來自己寫一個實際的例子瞭解下函式式介面的使用:

// 1.寫一個對傳入引數進行操作的函式式介面
@FunctionalInterface
public interface FuncTest {
  void operation(Integer x);
}

// 2.寫一個方法,將函式式,介面作為引數
private static Integer operate(Integer a,FuncTest funcTest) {
  return funcTest.operation(a);
}

// 3.使用函式式介面
System.out.println(operate(1,(x) -> x + x)); // 輸出 2

可以看到,我們在第3步才開始定義函式式介面的實際功能,對兩個數進行相加操作並返回結果。lambda的最大便捷之處就在於此,將程式碼作為引數傳遞,非常靈活,大大精簡我們的程式碼。

4. Java8內建的4種常用函式式介面

Consumer :消費型介面

方法:void accept(T t);

Consumer<String> consumer = x -> System.out.println(x);

consumer.accept("Hello"); // 列印Hello

Supplier :供給型介面

方法:T get();

Supplier<String> supplier = () -> "Hello";

System.out.println(supplier.get()); // 列印Hello

Function<T,R> :函式型介面

方法:R apply(T t);

Function function = x -> "Hello " + x;

System.out.println(function.apply("World"));

Predicate :斷言型介面

方法:boolean test(T t);

Predicate predicate = x -> x == "Hello";

System.out.println(predicate.test("Hello"));

ava.util.function 它包含了很多類,用來支援 Java的 函數語言程式設計,該包中的函式式介面有:

一文帶你徹底搞懂Lambda表示式

5. 總結

Java8引入lambda表示式是接收了函數語言程式設計語言的思想,例如scala之類的,它將函式視為一等公民,可以使用高階函式等。和指令式程式設計相比,函數語言程式設計強調函式的計算比指令的執行重要。和過程化程式設計相比,函數語言程式設計裡函式的計算可隨時呼叫。

lambda表示式可以使程式碼看起來簡潔,但一定程度上增加了程式碼的可讀性以及除錯的複雜性,所以在使用時應儘量是團隊都熟悉使用,要麼乾脆就別用,不然維護起來是件較痛苦的事。

以上這篇一文帶你徹底搞懂Lambda表示式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。