JAVA8 新特性 Stream 操作

Java8的兩個重大改變,一個是Lambda表達式,另一個就是本節要講的Stream API表達式。Stream 是Java8中處理集合的關鍵抽象概念,它可以對集合進行非常複雜的查找、過濾、篩選等操作。

1、Stream的操作步驟

Stream有如下三個操作步驟:

一、創建Stream

從一個數據源,如集合、數組中獲取流。

二、中間操作

一個操作的中間鏈,對數據源的數據進行操作。

三、終止操作

一個終止操作,執行中間操作鏈,併產生結果。

要注意的是,對流的操作完成後需要進行關閉操作(或者用JAVA7的try-with-resources)。

public static void main(String[] args) {

    // 1)找到年齡大於18歲的人並輸出;
    personList.stream().filter((p) -> p.getAge() > 18).forEach(System.out::println);

    System.out.println("-------------------------------------------");

    // 2)找出所有中國人的數量
    long chinaPersonNum = personList.stream().filter((p) -> p.getCountry().equals("中國")).count();
    System.out.println("中國人有:" + chinaPersonNum + "個");
}

上面的例子表示,我要查找personList集合中,所有國籍爲中國的人數量;遍歷輸出所有年齡大於18的人員信息。

2、Stream中間操作--篩選與切片

  • filter:接收Lambda,從流中排除某些操作;
  • limit:截斷流,使其元素不超過給定對象
  • skip(n):跳過元素,返回一個扔掉了前n個元素的流,若流中元素不足n個,則返回一個空流,與limit(n)互補
  • distinct:篩選,通過流所生成元素的hashCode()和equals()去除重複元素。

2.1 limit舉例

需求,從Person列表中取出兩個女性。

1 personList.stream().filter((p) -> p.getSex() == 'F').limit(2).forEach(System.out::println);

輸出結果爲:

Person(name=歐陽雪, age=18, country=中國, sex=F)
Person(name=Harley, age=22, country=英國, sex=F)

2.2 skip舉例

從Person列表中從第2個女性開始,取出所有的女性。

1 personList.stream().filter((p) -> p.getSex() == 'F').skip(1).forEach(System.out::println);

輸出結果爲:

Person(name=Harley, age=22, country=英國, sex=F)
Person(name=小梅, age=20, country=中國, sex=F)
Person(name=何雪, age=21, country=中國, sex=F)

2.3 distinct舉例

1 personList.stream().filter((p) -> p.getSex() == 'M').distinct().forEach(System.out::println);

輸出結果爲:

Person(name=Tom, age=24, country=美國, sex=M)
Person(name=向天笑, age=20, country=中國, sex=M)
Person(name=李康, age=22, country=中國, sex=M)

男性中有兩個李康,去除掉了一個重複的。

3、Stream中間操作--映射

  • map--接收Lambda,將元素轉換成其他形式或提取信息。接收一個函數作爲參數,該函數會被應用到每個元素上,並將其映射成一個新的元素。
  • flatMap--接收一個函數作爲參數,將流中的每個值都換成另一個流,然後把所有流連接成一個流

3.1 map舉例

        String[] words = new String[]{"Hello","World"};
        List<String[]> a = Arrays.stream(words)
                .map(word -> word.split(""))
                .distinct()
                .collect(toList());
        a.forEach(System.out::print);

 代碼輸出爲:[Ljava.lang.String;@12edcd21[Ljava.lang.String;@34c45dca (返回一個包含兩個String[]的list)

這個實現方式是由問題的,傳遞給map方法的lambda爲每個單詞生成了一個String[](String列表)。因此,map返回的流實際上是Stream<String[]> 類型的。你真正想要的是用Stream<String>來表示一個字符串。

下方圖是上方代碼stream的運行流程

3.2 flatMap舉例(對流扁平化處理)

        String[] words = new String[]{"Hello","World"};
        List<String> a = Arrays.stream(words)
                .map(word -> word.split(""))
                .flatMap(Arrays::stream)
                .distinct()
                .collect(toList());
        a.forEach(System.out::print);

結果輸出:HeloWrd

        使用flatMap方法的效果是,各個數組並不是分別映射一個流,而是映射成流的內容,所有使用map(Array::stream)時生成的單個流被合併起來,即扁平化爲一個流。

    下圖是運用flatMap的stream運行流程,

 其他Stream操作,請參考以下博客:

https://www.cnblogs.com/wuhenzhidu/p/10740091.html

https://blog.csdn.net/weixin_38361347/article/details/90247695

https://blog.csdn.net/weixin_33860722/article/details/93596115

 

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