国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java 8 新特性——Lambdas 表達式

2019-11-15 01:01:57
字體:
來源:轉載
供稿:網友
java 8 新特性——Lambdas 表達式本文內容
  • 引入
  • 測試數據
  • collect(toList())
  • map
  • filter
  • flatMap
  • max 和 min
  • reduce
  • 整合操作
  • 參考資料

Java 8 對核心類庫的改進主要包括集合類的 API 和新引入的流(Stream)。流使得程序員得以站在更高的抽象層次上對集合進行操作。

本文主要介紹 java.util.stream 中 Lambdas 表達式的使用。

下載 Demo 引入

假設有個藝術家的列表集合,后面會給出定義(藝術家包含名字,歌曲,國籍等屬性),在此先借用一下。若計算來自 UK 的藝術家的人數,如下代碼所示:

int count = 0;
for (Artist artist : allArtists) {
    if (artist.isFrom("UK")) {
        count++;
    }
}

很“簡單”、很“標準”的寫法,無非是遍歷一遍,如果是來自 UK 的,計數就增 1。

這段代碼是命令式的編程,包含太多樣板代碼,但樣板代碼模糊了代碼的本意,無法流暢地表達程序員的意圖。總體來看,for 循環會將行為和方法混為一談。個人認為,行為比方法抽象層次要高,一個行為可以由多個方法構成,也就是說,一個行為可能會經由多個方法來完成。

for 循環其實是一個封裝了迭代的語法糖。如下代碼所示:

int count = 0;
Iterator<Artist> iterator = allArtists.iterator();
while (iterator.hasNext()) {
    Artist artist = iterator.next();
    if (artist.isFrom("UK")) {
        count++;
    }
}

無論如何,上面的方式都不能達到抽象的目的,無法流程地表達意圖,而且,本質上都是一種串行化的操作。

下面用 Java 8 新特性 Stream 的方式實現上面功能,如下代碼所示:

long count = allArtists.stream().filter(artist -> artist.isFrom("UK")).count();

能夠清晰地表達意圖;如果想并行,可以在 Stream 上調用 Parallel 方法,再執行后續操作。

整個過程被分解為兩個更簡單的操作:過濾和計數,看似化簡為繁,多了一步,好像是執行了兩次循環,而事實上,類庫設計更精妙,只需對藝術家集合迭代一次。

這也是函數式編程的思想,假如給定一個名稱列表,有的只有一個字符。現要求用逗號做分割符,并返回列表中的名稱,字符串中不包含單字母名稱,每個名稱的首字母都大寫。代碼很容易寫,關鍵在于用什么思想。這里本質上執行了三個任務:篩選,列表以消除單字符,將列表中每個名稱的首字母變換 為大寫,然后將列表轉化 為一個字符串。在命令式語言中,不得不為三個任務都使用同一低級機制(對列表進行迭代)。函數式語言將篩選、變換和轉化視為常見操作,因此它們提供給您從不同視角解決問題的方式。

Scala 分別為篩選、變換和轉化概念使用了行業通用的名稱,即 filter、map 和 reduce。你會下接下來的 Java 8 中看到類似的類庫。

測試數據

Track、Album、Artist 類的具體定義,查看 Demo。你可以想象,假設你有一張 CD,Album 是專輯,就是這張 CD;一個 Album 包含多個音樂,Track 就是每個音樂,其包含音樂名和時長;Artist 就是張 CD 的藝術家,他可能是個人,也可能是團隊。

package com.example.java8lambdas.data;
 
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
 
import com.example.java8lambdas.base.Album;
import com.example.java8lambdas.base.Artist;
import com.example.java8lambdas.base.Track;
 
import static java.util.Arrays.asList;
 
public class SampleData {
 
    public static final Artist johnColtrane = new Artist("John Coltrane", "US");
    public static final Artist johnLennon = new Artist("John Lennon", "UK");
    public static final Artist paulMcCartney = new Artist("Paul McCartney", "UK");
    public static final Artist georgeHarrison = new Artist("George Harrison", "UK");
    public static final Artist ringoStarr = new Artist("Ringo Starr", "UK");
 
    public static final List<Artist> membersOfTheBeatles = Arrays.asList(johnLennon, paulMcCartney, georgeHarrison,
            ringoStarr);
    public static final Artist theBeatles = new Artist("The Beatles", membersOfTheBeatles, "UK");
 
    public static final Album aLoveSuPReme = new Album("A Love Supreme",
            asList(new Track("Acknowledgement", 467), new Track("Resolution", 442)), asList(johnColtrane));
 
    public static final Album sampleShortAlbum = new Album("sample Short Album", asList(new Track("short track", 30)),
            asList(johnColtrane));
 
    public static final Album manyTrackAlbum = new Album(
            "sample Short Album", asList(new Track("short track", 30), new Track("short track 2", 30),
                    new Track("short track 3", 30), new Track("short track 4", 30), new Track("short track 5", 30)),
            asList(johnColtrane));
 
    public static Stream<Album> albums = Stream.of(aLoveSupreme);
 
    public static Stream<Artist> threeArtists() {
        return Stream.of(johnColtrane, johnLennon, theBeatles);
    }
 
    public static List<Artist> getThreeArtists() {
        return Arrays.asList(johnColtrane, johnLennon, theBeatles);
    }
 
    public static List<Album> getAlbum() {
        return Arrays.asList(aLoveSupreme, sampleShortAlbum, manyTrackAlbum);
    }
}
collect(toList())

由Stream 里的值生成一個列表,這是一個及早求值操作。很多 Stream 操作都是惰性求值,因此,調用 Stream 上的一系列方法后,還需要最后再調用一個類似 collect 的及早求值方法。

所謂,惰性求值方法,最終不產生新集合的方法,Stream 大部分方法都是惰性求值;而像 count 這樣最終會從 Stream 產生值的方法是及早求值方法。判斷一個操作是惰性求值還是及早求值,只需看它的返回值。如果返回值是 Stream,那么就是惰性求值;否則,就是及早求值。

Stream.of(johnColtrane, johnLennon, theBeatles).collect(toList())
把三個藝術家變成一個 List<Artist> 集合。 map

將一種類型的值轉換成另一種類型,也就是,將一個流中的值轉換成一個新的流。若有一個 List<Artist> 列表 artists,則

List<String> collects = artists.stream().map(artist -> artist.getName()).collect(toList());

返回所有藝術家的名字。注意,返回的是字符串列表。藝術家包含眾多屬性,但最后我需要的只是他們的名字。

Java 8 引入了方法引用的概念,因此,上面的代碼也可以寫成,“類名::方法”的形式:

artists.stream().map(Artist::getName).collect(toList());

map,映射,也可以完成數據類型轉換,如下面代碼,將字符串轉換成大寫;將字符串轉換成整型;將十六進制轉換成十進制:


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鹤庆县| 宣威市| 虞城县| 揭西县| 诸城市| 迁西县| 萨迦县| 枣强县| 夏邑县| 景德镇市| 天柱县| 汉阴县| 富民县| 修文县| 纳雍县| 岳阳县| 桃江县| 宜城市| 崇仁县| 萝北县| 黑山县| 扎兰屯市| 天门市| 班戈县| 林芝县| 晴隆县| 锡林郭勒盟| 济阳县| 石门县| 咸宁市| 宜宾县| 和田市| 马关县| 墨脱县| 乐山市| 永州市| 黄陵县| 武平县| 高台县| 保康县| 浦县|