前言:Lambda 是一個匿名函式,我們可以把 Lambda 運算式理解為是一段可以傳遞的代碼(將代碼像資料一樣進行傳遞),使用它可以寫出更簡潔、更靈活的代碼,作為一種更緊湊的代碼風格,使Java的語言表達能力得到了提升,
代碼舉例:
@Test
public void test1(){
//匿名實作類的非匿名物件
Runnable runnable = new Runnable(){
@Override
public void run() {
System.out.println("This is test");
}
};
runnable.run();
//Lambda運算式
Runnable runnable1 = () -> System.out.println("This is test");
runnable1.run();
}
輸出結果:
This is test
This is test
Process finished with exit code 0
相信初學者看到這里會有所不明白,那么下面我們將詳細說明Lambda運算式,
一.Lambda運算式的語法
在Java 8 語言中引入了一種新的語法元素和運算子,這個運算子為 “->” , 該運算子被稱為 Lambda 運算子或箭頭運算子,它將 Lambda 分為兩個部分:
- 左側:指定了 Lambda 運算式需要的引數串列
- 右側:指定了 Lambda 體,是抽象方法的實作邏輯,也即 Lambda 運算式要執行的功能,
Lambda運算式的本質是作為函式式介面的實體,
1. 無參,無回傳值
@Test
public void test1(){
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("This is test!!!");
}
};
//1. 無參,無回傳值
Runnable runnable1 = () -> {
System.out.println("This is test!");
};
}
2.有一個引數,但是沒有回傳值,
@Test
public void test2(){
Consumer<String> consumer = new Consumer<>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
//2.有一個引數,但是沒有回傳值,
Consumer<String> consumer1 = (String s) -> {
System.out.println(s);
};
}
3.資料型別可以省略,因為可由編譯器推斷得出(型別推斷)
@Test
public void test2(){
Consumer<String> consumer = new Consumer<>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
//2.有一個引數,但是沒有回傳值,
Consumer<String> consumer1 = (String s) -> {
System.out.println(s);
};
//3.資料型別可以省略,因為可由編譯器推斷得出(型別推斷)
Consumer<String> consumer2 = (s) -> {
System.out.println(s);
};
}
4.Lambda 若只需要一個引數時,引數的小括號可以省略
@Test
public void test2(){
Consumer<String> consumer = new Consumer<>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
//2.有一個引數,但是沒有回傳值,
Consumer<String> consumer1 = (String s) -> {
System.out.println(s);
};
//3.資料型別可以省略,因為可由編譯器推斷得出(型別推斷)
Consumer<String> consumer2 = (s) -> {
System.out.println(s);
};
//4.Lambda 若只需要一個引數時,引數的小括號可以省略
Consumer<String> consumer3 = s ->{
System.out.println(s);
};
}
5.Lambda 需要兩個或以上的引數,多條執行陳述句,并且可以有回傳值
@Test
public void test3(){
Comparator<Integer> comparator = new Comparator<>() {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println("函式式介面方法!");
return Integer.compare(o1, o2);
}
};
//5.Lambda 需要兩個或以上的引數,多條執行陳述句,并且可以有回傳值
Comparator<Integer> comparator1 = (x,y) -> {
System.out.println("函式式介面方法!");
return Integer.compare(x,y);
};
}
6.當 Lambda 體只有一條陳述句時,return 與大括號若有,都可以省略
@Test
public void test3(){
Comparator<Integer> comparator = new Comparator<>() {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println("函式式介面方法!");
return Integer.compare(o1, o2);
}
};
//5.Lambda 需要兩個或以上的引數,多條執行陳述句,并且可以有回傳值
Comparator<Integer> comparator1 = (x,y) -> {
System.out.println("函式式介面方法!");
return Integer.compare(x,y);
};
//6.當 Lambda 體只有一條陳述句時,return 與大括號若有,都可以省略
// 6.1
Comparator<Integer> comparator2 = (x,y) -> {
return Integer.compare(x,y);
};
//6.2
Comparator<Integer> comparator3 = (x,y) -> Integer.compare(x,y);
}
@Test
public void test2(){
Consumer<String> consumer = new Consumer<>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
//2.有一個引數,但是沒有回傳值,
Consumer<String> consumer1 = (String s) -> {
System.out.println(s);
};
//3.資料型別可以省略,因為可由編譯器推斷得出(型別推斷)
Consumer<String> consumer2 = (s) -> {
System.out.println(s);
};
//4.Lambda 若只需要一個引數時,引數的小括號可以省略
Consumer<String> consumer3 = s ->{
System.out.println(s);
};
//6.當 Lambda 體只有一條陳述句時,return 與大括號若有,都可以省略
Consumer<String> consumer4 = s -> System.out.println(s);
}
二.型別推斷說明
上述 Lambda 運算式中的引數型別都是由編譯器推斷得出的,Lambda 運算式中無需指定型別,程式依然可以編譯,這是因為 javac 根據程式的背景關系,在后臺推斷出了引數的型別,Lambda 運算式的型別依賴于背景關系環境,是由編譯器推斷出來的,這就是所謂的“型別推斷”,
例如:
Consumer<String> consumer = new Consumer<>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
//資料型別可以省略,因為可由編譯器推斷得出(型別推斷)
Consumer<String> consumer2 = (s) -> {
System.out.println(s);
};
三.Lambda運算式與函式式介面
- Java從誕生日起就是一直倡導“一切皆物件”,在Java里面面向物件(OOP) 編程是一切,但是隨著python、scala等語言的興起和新技術的挑戰,Java不 得不做出調整以便支持更加廣泛的技術要求,也即java不但可以支持OOP還 可以支持OOF(面向函式編程),在函式式編程語言當中,函式被當做一等公民對待,在將函式作為一等公民的 編程語言中,Lambda運算式的型別是函式,但是在Java8中,有所不同,在 Java8中,Lambda運算式是物件,而不是函式,它們必須依附于一類特別的 物件型別——函式式介面,
- 簡單的說,在Java8中,Lambda運算式就是一個函式式介面的實體,這就是 Lambda運算式和函式式介面的關系,也就是說,只要一個物件是函式式介面的實體,那么該物件就可以用Lambda運算式來表示,所以以前用匿名實作類表示的現在都可以用Lambda運算式來寫,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/234870.html
標籤:java
