真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

java8的Lambda表達式怎么應(yīng)用

這篇文章主要介紹“java8的Lambda表達式怎么應(yīng)用”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“java8的Lambda表達式怎么應(yīng)用”文章能幫助大家解決問題。

十多年的浦口網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。網(wǎng)絡(luò)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整浦口建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。成都創(chuàng)新互聯(lián)公司從事“浦口網(wǎng)站設(shè)計”,“浦口網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。

Lambda 表達式

前片文章講到,使用匿名類來表示不同的行為并不令人滿意:代碼十分啰嗦,這會影響程序
員在實踐中使用行為參數(shù)化的積極性。在本章中,我們會教給你Java 8中解決這個問題的新工
具——Lambda表達式。它可以讓你很簡潔地表示一個行為或傳遞代碼?,F(xiàn)在你可以把Lambda
表達式看作匿名功能,它基本上就是沒有聲明名稱的方法,但和匿名類一樣,它也可以作為參
數(shù)傳遞給一個方法。

Lambda 管中窺豹

可以吧Lambda表達式簡單的理解為可以可以傳遞匿名函數(shù)的一種形式:它沒有名稱,但是有參數(shù)列表,函數(shù)主體,返回類型,甚至還可以有一個可以拋出異常的函數(shù)列表.

  • 匿名:我們說匿名,是因為它不像普通的方法那樣有一個明確的名稱:寫得少而想得多!

  • 函數(shù): 我們說它是函數(shù),是因為Lambda函數(shù)不像方法那樣屬于某個特定的類。但和方法一樣,Lambda有參數(shù)列表、函數(shù)主體、返回類型,還可能有可以拋出的異常列表。

  • 傳遞:Lambda表達式可以作為參數(shù)傳遞給方法或存儲在變量中.

  • 簡潔:無需像匿名類那樣寫很多模版代碼.

在前面的講解中,我們寫過一個簡單的Lambda表達式

可以看到,Lambda表達式有三個部分:
* 參數(shù)列表:這里它采用了 Comparator 中 compare 方法的參數(shù),兩個 Apple 。
* 箭頭:把參數(shù)和函數(shù)主題分開.
* Lambda主體: 比較兩個 Apple 的重量。表達式就是Lambda的返回值了。

為了進一步說明,下面給出了Java 8中五個有效的Lambda表達式的例子。

java語言設(shè)計者選擇這樣的語法,是因為C#和Scala等語言中的類似功能廣受歡迎.Lambda的基本語法就是:

(parameters) -> expression

或(請注意語句的花括號)

(parameters) -> { statements; }

函數(shù)式接口

一言以蔽之,函數(shù)式接口就是只定義一個抽象方法的接口。

如我們前面創(chuàng)建的:

public interface Predicate{
      boolean

函數(shù)描述符

函數(shù)式接口的抽象方法的簽名基本上就是Lambda表達式的簽名,我們將這種抽象方法叫做函數(shù)描述符.

這很好理解:因為函數(shù)式接口只有一個抽象方法,因此我們只需要知道參數(shù)列表,和返回值就可以描述這個函數(shù).

例如, Runnable 接口可以看作一個什么也不接受什么也不返回( void )的函數(shù)的
簽名,因為它只有一個叫作 run 的抽象方法,這個方法什么也不接受,什么也不返回( void )。

使用函數(shù)式接口

函數(shù)式接口定義且只定義了一個抽象方法.函數(shù)式接口很有用,因為抽象方法的簽名可以描述為Lambda表達式的簽名

函數(shù)式接口的抽象方法的簽名稱為函數(shù)描述符.

Java API中已經(jīng)有了幾個函數(shù)式接口

Java 8的庫設(shè)計師幫你在 java.util.function 包中引入了幾個新的函數(shù)式接口。我們接下
來會介紹 Predicate 、 Consumer 和 Function ,更完整的可以查看API.

為了總結(jié)關(guān)于函數(shù)式接口和Lambda的討論,表3-3總結(jié)了一些使用案例、Lambda的例子,以
及可以使用的函數(shù)式接口。

java8的Lambda表達式怎么應(yīng)用

類型檢查

Lambda表達式的類型是從Lambda的上下文中推斷出來的,上下文中Lambda表達式需要的類型稱為目標類型.

舉個上節(jié)中的例子:

類型推斷

java編譯器可以從上下文中推斷出用什么函數(shù)式接口來配合Lambda表達式,這意味著他可以推斷出適合Lambda表達式的簽名,因為函數(shù)描述符也可以從目標類型中得到.
這樣做的好處在于,編譯器可以了解Lambda表達式的參數(shù)類型

Lambda表達式有多個參數(shù),代碼可讀性的好處就更為明顯。例如,你可以這樣來創(chuàng)建一個
Comparator 對象:

請注意,有時候顯式寫出類型更易讀,有時候去掉它們更易讀。沒有什么法則說哪種更好;
對于如何讓代碼更易讀,程序員必須做出自己的選擇

使用局部變量

Lambda表達式也允許使用自有變量(不是參數(shù),是在外層作用域定義的變量),就想匿名類一樣,他們被稱為捕獲Lambda

int portNumber = 1337;
Runnable r = () -> System.out.println(portNumber);

需要注意的是:盡管Lambda可以沒有限制地捕獲(也就是在其主體中引用)實例變量和靜態(tài)變量。但是局部變量必須顯示聲明為final,或者事實上就是final.
換句話說:Lambda表達式只能捕獲指派給他們的局部變量一次((注:捕獲實例變量可以被看作捕獲最終局部變量 this 。)),

例如,下面的代碼無法編譯,因為 portNumber

變量被賦值兩次:

對局部變量的限制

你可能會問自己,為什么局部變量有這些限制?????

第一,實例變量和局部變量背后的實現(xiàn)有一個關(guān)鍵的不同,實例變量存儲在堆中,局部變量存儲在棧中,
如果Lambda可以直接訪問局
部變量,而且Lambda是在一個線程中使用的,則使用Lambda的線程,可能會在分配該變量的線
程將這個變量收回之后,去訪問該變量。因此,Java在訪問自由局部變量時,實際上是在訪問它
的副本,而不是訪問原始變量。如果局部變量僅僅賦值一次那就沒有什么區(qū)別了——因此就有了
這個限制。

第二,這一限制不鼓勵你使用改變外部變量的典型命令式編程模式(我們會在以后的各章中
解釋,這種模式會阻礙很容易做到的并行處理)

閉包:
你可能已經(jīng)聽說過閉包這個詞,你可能會想Lambda是否滿足閉包的定義.科學的講,閉包就是一個函數(shù)的實例.且它可以無限制的訪問那個函數(shù)的非本地變量.
例如,閉包可以作為參數(shù)傳遞給另一個函數(shù)。它也可以訪
問和修改其作用域之外的變量。現(xiàn)在,Java 8的Lambda和匿名類可以做類似于閉包的事情:它們可以作為參數(shù)傳遞給方法,并且可以訪問其作用域之外的變量.
但是有一個限制:就是它們不能修改定義Lambda的方法的局部變量的內(nèi)容.這些變量必須是隱式最終的.可以認為Lambda是對值封閉,而不是對變量封閉.

如前所述: 這種限制的原因在于局部變量保存在棧上,并且隱式表示它們僅限于其所在線程.如果允許捕獲局部變量,就會引發(fā)造成線程不安全的新得可能性,而這時我們不想看到的
實例變量是可以的,因為它們保存在堆中,而堆是在線程中共享的.

管中窺豹之 方法引用

方法引用可以被看作是調(diào)用Lambda表達式的一種快捷方法.

它的基本思想是:

如果一個Lambda表達式代表是 直接調(diào)用這個方法,那最好還是用名稱來調(diào)用它.
事實上,方法引用就是讓你根據(jù)已有的方法來創(chuàng)建Lambda表達式.

它是如何工作的呢?

當你需要使用方法引用時,目標引用放在分隔符 :: 前,方法名放在后面.

例如,
Apple::getWeight 就是引用了 Apple 類中定義的方法 getWeight 。請記住,不需要括號,因為
你沒有實際調(diào)用這個方法。方法引用就是Lambda表達式 (Apple a) -> a.getWeight() 的快捷
寫法。

/**
     * 方法引用
     */
    @Test
    public void test5(){

        List inventory1 = initInventory();
        inventory1.sort((Apple a1, Apple a2)-> a1.getWeight().compareTo(a2.getWeight()));
        System.out.println(inventory1);

        List inventory = initInventory();
        inventory.sort(Comparator.comparing(Apple::getWeight));
        System.out.println(inventory);

    }

現(xiàn)在讓我們用一個上節(jié)中對蘋果排序的例子貫穿一下我們目前接觸到的所有知識

Lambda 和方法引用實戰(zhàn)

我們想要實現(xiàn)的最終解決方案是這樣的:

inventory.sort(comparing(Apple::getWeight));

第 1 步:傳遞代碼:

Java 8的API已經(jīng)為你提供了一個 List 可用的 sort 方法,你不用自己去實現(xiàn)它。
那么最困難的部分已經(jīng)搞定了!但是,如何把排序策略傳遞給 sort 方法呢?你看, sort 方法的
簽名是這樣的:

void sort(Comparator

它需要一個Comparator對象來比較兩個Apple,這就是zaijava中傳遞策略的方式:他們必須包裹在一個對象里,
我們說 sort 的行為被參數(shù)化了:傳遞給它的排序策略不同,其行為也會不同.

你的第一個解決方案看上去是這樣的:

public class AppleComparator implements Comparator {
    public int compare(Apple a1, Apple a2){
     return a1.getWeight().compareTo(a2.getWeight());
    }
}
    inventory.sort(new

第 2 步:使用匿名類

你可以使用匿名類來改進解決方案,而不是實現(xiàn)一個 Comparator 卻只實
例化一次:

inventory.sort(new Comparator() {
    public int compare(Apple a1, Apple a2){
        return

第 3 步:使用 Lambda 表達式

但你的解決方案仍然挺啰嗦的。Java 8引入了Lambda表達式,它提供了一種輕量級語法來實
現(xiàn)相同的目標:傳遞代碼

inventory.sort((Apple a1, Apple a2)-> a1.getWeight().compareTo(a2.getWeight()));

我們前面解釋過了,Java編譯器可以根據(jù)Lambda出現(xiàn)的上下文來推斷Lambda表達式參數(shù)的
類型。那么你的解決方案就可以重寫成這樣:

inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()));

你的代碼還能變得更易讀一點嗎???

Comparator 具有一個叫做Comparing的靜態(tài)輔助方法,方法描述如下:

public static > Comparator comparing(
            Function keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return

可以看到,它可以接受一個Function來提取一個鍵值,并生成一個Compartor對象.

它可以像下面這樣用(注意你現(xiàn)在傳遞的Lambda只有一
個參數(shù):Lambda說明了如何從蘋果中提取需要比較的鍵值):

Comparator c = Comparator.comparing((Apple a) -> a.getWeight());

因此,現(xiàn)在你可以該代碼改為這樣:

import static

第 4 步:使用方法引用

方法引用就是替代那些轉(zhuǎn)發(fā)參數(shù)的Lambda表達式的語法糖.
你可以使用方法引用讓你的代碼更簡潔,假設(shè)你靜態(tài)導入了 java.util.Comparator.comparing.
那么你現(xiàn)在的代碼可以這樣:

inventory.sort(comparing(Apple::getWeight));

關(guān)于“java8的Lambda表達式怎么應(yīng)用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。


網(wǎng)頁標題:java8的Lambda表達式怎么應(yīng)用
轉(zhuǎn)載來源:http://weahome.cn/article/jogjds.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部