欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java函數(shù)式編程(三):列表的轉(zhuǎn)化

 更新時間:2014年09月25日 11:52:41   作者:deepinmind  
這篇文章主要介紹了Java函數(shù)式編程(二):列表的轉(zhuǎn)化,lambda表達式不僅能幫助我們遍歷集合,并且可以進行集合的轉(zhuǎn)化,需要的朋友可以參考下

列表的轉(zhuǎn)化

將集合轉(zhuǎn)化成一個新的集合就和遍歷它一樣簡單。假設(shè)我們要將列表中的名字轉(zhuǎn)化成全大寫的。我們看下都有哪些實現(xiàn)方式。

Java中的字符串是不可變的,所以它沒法改變。我們可以生成新的字符串,用來替換列表中原有的元素。然而這樣做的話,原來列表就沒了;還有一個問題,原來的列表可能也是不可變的,比如Arrays.asList()生成的,所以修改原來的列表這招不行。還有一個缺點就是這樣做很難并行操作。

生成一個新的全大寫的列表是個不錯的選擇。

乍聽起來這個建議弱爆了;性能是我們都很關(guān)注的一個問題。令人吃驚的是,函數(shù)式編程通常要比命令式的性能要高,我們在153頁的性能問題中會講到。

我們先開始用這個集合生成一個大寫字母的新集合吧。

復(fù)制代碼 代碼如下:

final List<String> uppercaseNames = new ArrayList<String>();
for(String name : friends) {
uppercaseNames.add(name.toUpperCase());
}

在命令式的代碼中,我們先創(chuàng)建一個空列表,然后把大寫的名字填充進去,在遍歷原來列表的過程中,每次插入一個。為了改進成函數(shù)式的版本,我們第一步可以考慮采用19頁遍歷列表中提到的那個內(nèi)部迭代器forEach來替換一下for循環(huán),正如下例所示的那樣。
復(fù)制代碼 代碼如下:

final List<String> uppercaseNames = new ArrayList<String>();
friends.forEach(name -> uppercaseNames.add(name.toUpperCase()));
System.out.println(uppercaseNames);

我們用了內(nèi)部迭代器,但還得新建一個列表,然后再把元素插入到里面。我們還可以進一步改進。

使用lambda表達式

一個新引入的Stream接口里面,有個map方法,它可以幫助我們遠(yuǎn)離可變性,并使代碼看起來更簡潔。Steam有點像集合的迭代器,同時它還提供了流函數(shù)(fluent functions)的功能。使用這個接口的方法,我們可以把一系列調(diào)用給組合起來,使代碼讀起來就像描述問題的順序一樣,可讀性更強。

Steam的map方法可以用來將輸入序列轉(zhuǎn)化成一個輸出的序列——這和我們要做的工作非常匹配。

復(fù)制代碼 代碼如下:

friends.stream()
.map(name -> name.toUpperCase())
.forEach(name -> System.out.print(name + " "));
System.out.println();

JDK8中的所有集合都支持這個stream方法,它把集合封裝成一個Steam實例。map方法對Stream中的每個元素都調(diào)用了指定的lambda表達式或者代碼塊。map方法跟forEach方法很不一樣, forEach只是簡單的對集合中的元素執(zhí)行了一下指定的函數(shù)。而map方法把lambda表達式的運行結(jié)果收齊起來,返回一個結(jié)果集。最后我們用forEach方法打印了所有的元素。

新集合中的名字全都是大寫的了:

復(fù)制代碼 代碼如下:

BRIAN NATE NEAL RAJU SARA SCOTT

map方法很適合把一個輸入集合轉(zhuǎn)化成一個新的輸出集合。這個方法確保了輸入輸出序列的元素的數(shù)量是相同的。然而輸入元素和輸出元素的類型可以是不一樣的。在這個例子中,我們輸入和輸出的都是字符串的集合。我們可以傳給map方法一段代碼,讓它返回比如說名字中包含字符的個數(shù)。這樣的話,輸入的還是字符串的序列,而輸出的卻是數(shù)字序列了,就像下面這樣。

復(fù)制代碼 代碼如下:

friends.stream()
.map(name -> name.length())
.forEach(count -> System.out.print(count + " "));

結(jié)果是每個名字中字母的個數(shù):
復(fù)制代碼 代碼如下:

5 4 4 4 4 5

使用了lambda表達式的之后版本,避免了顯式的修改操作;這樣的代碼非常簡潔。這樣寫不再需要初始化空的集合以及那個垃圾變量了;這個變量乖乖的躲到了底層實現(xiàn)里面了。

使用方法引用

我們還可以使用方法引用讓它變得更簡潔一些。在需要傳入函數(shù)式接口的實現(xiàn)的地方,Java編譯器可以接受lambda表達式或者是方法引用。有了這個特性,用String::toUpperCase就可以替換掉name -> name.toUpperCase()了,就像這樣:

復(fù)制代碼 代碼如下:

friends.stream()
.map(String::toUpperCase)
.forEach(name -> System.out.println(name));

當(dāng)參數(shù)傳入到這個生成的方法——函數(shù)式接口的抽象方法的實現(xiàn)——里面的時候,Java會去調(diào)用這個String參數(shù)的toUpperCase方法。這個參數(shù)引用在這里就隱藏起來了。像前面這種簡單的場景,我們可以用方法引用來替換掉lambda表達式;更多的內(nèi)容看一下26頁的什么時候應(yīng)該使用方法引用。

復(fù)制代碼 代碼如下:

小伙伴發(fā)問了:
什么時候應(yīng)該使用方法引用?

當(dāng)使用Java編程的時候,通常我們用lambda表達式的時候要比方法引用多得多。但這并不意味著方法引用不重要或者沒啥用處。當(dāng)lambda表達式非常簡短的時候,它是一個很好的替代方案,它直接調(diào)用了實例方法或者靜態(tài)方法。也就是說,如果lambda表達式只是傳遞了一下參數(shù)給方法調(diào)用的話,我們應(yīng)該改用方法引用。
像這樣的lambda表達式,有點像Tom Smykowski在電影上班一條蟲中講的那樣,它的工作就是"從客戶那把需求拿給軟件工程師"。因為這個,我把這種重構(gòu)成方法引用的模式叫做上班一條蟲模式。
除了簡潔外,使用方法引用,方法名字本身的含義和作用可以更好的體現(xiàn)出來。
使用方法引用背后,編譯器起到了很關(guān)鍵的作用。方法引用的目標(biāo)對象和參數(shù)都會從這個生成的方法里傳進來的參數(shù)那推導(dǎo)出來。這才使得你可以使用方法引用寫出比使用lambda表達式更簡潔的代碼。不過,如果參數(shù)在傳遞給方法之前或者調(diào)用結(jié)果在返回之后要被修改的話,這種便利的寫法我們就用不了了。

在前面這個例子中,方法引用是引用了一個實例方法。方法引用還可以引用一個靜態(tài)方法以及接受傳參的方法。后面我們會看到這樣的例子。

lambda表達式能幫助我們遍歷集合,并且進行集合的轉(zhuǎn)化。就像下面我們即將看到的,它還能幫助我們快速的從集合中選取一個元素。

相關(guān)文章

  • 詳解Spring中的FactoryBean

    詳解Spring中的FactoryBean

    本篇文章主要介紹了Spring中的FactoryBean,如果一個bean的創(chuàng)建過程中涉及到很多其他的bean 和復(fù)雜的邏輯,用xml配置比較困難,這時可以考慮用FactoryBean
    2017-04-04
  • Java中的Timer與TimerTask原理詳解

    Java中的Timer與TimerTask原理詳解

    這篇文章主要介紹了Java中的Timer與TimerTask原理詳解,timerTask本身沒什么意義,只是和timer集合操作的一個對象,實現(xiàn)它就必然有對應(yīng)的run方法,以被調(diào)用,他甚至于根本不需要實現(xiàn)Runnable,需要的朋友可以參考下
    2023-07-07
  • 基于sharding-jdbc的使用限制

    基于sharding-jdbc的使用限制

    這篇文章主要介紹了sharding-jdbc的使用限制,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • 深入理解Java注解的使用方法

    深入理解Java注解的使用方法

    這篇文章主要為大家詳細(xì)介紹了Java注解的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • SpringBoot2整合Redis多數(shù)據(jù)源步驟詳解

    SpringBoot2整合Redis多數(shù)據(jù)源步驟詳解

    這篇文章主要介紹了SpringBoot2整合Redis多數(shù)據(jù)源步驟詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • Java 異步實現(xiàn)的幾種方式小結(jié)

    Java 異步實現(xiàn)的幾種方式小結(jié)

    這篇文章主要介紹了Java 異步實現(xiàn)的幾種方式小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java設(shè)計模式之組合模式(Composite)

    java設(shè)計模式之組合模式(Composite)

    這篇文章主要為大家詳細(xì)介紹了java設(shè)計模式之組合模式Composite,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Ubuntu快速安裝eclipse

    Ubuntu快速安裝eclipse

    這篇文章主要為大家詳細(xì)介紹了Ubuntu快速安裝eclipse的簡單教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • MyBatis一級緩存避坑完全指南

    MyBatis一級緩存避坑完全指南

    這篇文章主要給大家介紹了關(guān)于MyBatis一級緩存避坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • 基于JDBC訪問MySql公共方法實例解析

    基于JDBC訪問MySql公共方法實例解析

    這篇文章主要介紹了基于JDBC訪問MySql公共方法實例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10

最新評論