帶你走進Java8之Lambda表達式

1.什麼是Lamdba?

Lambda是一個匿名函數,我們可以把Lambda表達式理解爲是一段可以傳遞的代碼。

2.Lamdba的結構?

在這裏插入圖片描述
一個lambda分爲三部分:參數列表、操作符、lambda體。
它的具體特徵有哪些呢?
可選類型聲明: 不需要聲明參數類型,編譯器可以統一識別參數值。
就是說(s) -> System.out.println(s)和 (String s) -> System.out.println(s)是一樣的編譯器會進行類型推斷所以不需要添加參數類型。
可選的參數圓括號: 一個參數無需定義圓括號,但多個參數需要定義圓括號。如下:
(1) s -> System.out.println(s) 一個參數不需要添加圓括號。
(2) (x, y) -> Integer.compare(y, x) 兩個參數添加了圓括號,否則編譯器直接報錯。

a-1.可選的大括號: 如果lambda體包含了一個語句,就不需要使用大括號。
s -> System.out.println(s) , 不需要大括號.
(s) -> { if (s.equals(“s”)){ System.out.println(s); } }; 需要大括號

a-2. 可選的返回關鍵字: 如果lambda體只有一個表達式返回值則編譯器會自動返回值,大括號需要指定明表達式返回了一個數值。

 //Lambda體不加{ }就不用寫return:
 Comparator<Integer> com = (x, y) -> Integer.compare(y, x); 
 //Lambda體加上{ }就需要添加return:
  Comparator<Integer> com = (x, y) -> {
            int compare = Integer.compare(y, x);
            return compare;
        }; 
3.Lamdba的類型判斷?

上面提及到lambda中有一個重要特徵就是可選參數類型聲明,意思是說不用寫參數的類型,那麼爲什麼不用寫呢?它是怎麼知道的參數類型呢?這就涉及到類型推斷了。

java8的泛型類型推斷改進:

(1) 支持通過方法上下文推斷泛型目標類型。
(2) 支持在方法調用鏈路中,泛型類型推斷傳遞到最後一個方法。

//下面代碼中,u的類型是List<User>,所以u.stream()的返回類型是Stream<User>.
//map()方法接收一個類型爲Function<T, R>的函數式接口,這裏T的類型即是Stream元素的類型,也就是User,而R的類型未知。
//由於在重載解析之後lambda表達式的目標類型仍然未知,我們就需要推導R的類型:通過對lambda表達式lambda進行類型檢查,我們發現lambda體返回String。
//因此R的類型是String,因而map()返回Stream<String>。
List<User> u = ...
Stream<String> names = u.stream().map(n -> n.getName());

假如碰到無法解析的情況:

//1.使用顯式lambda表達式(爲參數n提供顯式類型)以提供額外的類型信息
//2.把lambda表達式轉型爲Function<User, String>
//3.爲泛型參數R提供一個實際類型。( <String>map(n -> n.getName()))
4.方法引用?

方法引用是用來直接訪問類或者實例已經存在的方法或構造方法,提供了一種引用而不執行方法的方式。
當Lambda表達式中只是執行一個方法調用時,直接使用方法引用的形式可讀性更高一些。

寫法:
方法引用使用 “ :: ” 操作符來表示,左邊是類名或實例名右邊是方法名
(注意:方法引用::右邊的方法名是不需要加()的,例:User::getName)

關於方法引用的幾種方式:
類 :: 靜態方法(static)
類 :: 實例方法
對象 :: 實例方法

例如:
    Function<String, Integer> stringToInteger = (String s) -> Integer.parseInt(s);
等同於:
    Function<String, Integer> stringToInteger = Integer::parseInt;

注意:
Lambda體中調用方法的參數列表與返回值類型,要與函數式接口中抽象方法的函數列表和返回值類型保存一致。
若Lambda參數列表中的第一個參數是實例方法的調用者,而第二個參數是實例方法的參數時,可以使用ClassName::method。

5.構造器的引用?

語法格式:類名::new

例如:
    Supplier<User> supplier = ()->new User();

等同於:
    Supplier<User> supplier = User::new;

注意:需要調用的構造器方法與函數式接口中抽象方法的參數列表保持一致。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章