国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

引入流

phodal / 1315人閱讀

摘要:流的使用一般包括三件事一個數據源來執行一個查詢一個中間操作鏈,形成一條流水線一個終端操作,執行流水線并生成結果以上便是流的一些基礎知識,下一章會更加深入理解流。實戰第四章引入流讀書筆記歡迎加入咖啡館的春天。

流是什么

幾乎每個 Java 應用都會制造和處理集合。 允許我們以聲明性方式處理集合(通過類似于 SQL 查詢語句來表達,而不是臨時寫一個實現)。此外 還可以透明地并行處理,無需寫任何多線程代碼。

先看一個例子,混混眼熟就行

        List result = dishList
                .parallelStream()
                // 過濾
                .filter(d -> d.getCalories() < 400)
                // 排序
                .sorted(Comparator.comparing(Dish::getCalories))
                // 映射
                .map(Dish::getName)
                // 保存
                .collect(Collectors.toList());

而且以 parallelStream 調用會利用多核架構并行執行這段代碼,如果想要單線程處理,只需要把 parallelStream 換成 stream。

從代碼可以看出,它是以聲明性方式寫的:filter、sorted、map 和 collect。如同 SQL 中的 SELECT、FROM、WHERE 一樣。

Java 8中的 Stream API 可以

聲明性:更簡潔

可復合:更靈活

可并行:性能更好

流簡介

流的定義是 從支持數據處理操作的源生成的元素序列

元素序列:流提供了一個接口,可以訪問特定元素類型的一組有序值

源:流會使用一個提供數據的源,如集合、數組或輸出/輸出

數據處理操作:流的數據處理功能支持類似數據庫的聲明式操作,可以串行處理也可并行

流水線:很多流操作本身會返回一個流,這樣多個操作就可以鏈接起來,形成一個大的流水線

內部迭代:與使用迭代器顯式迭代不同,流的迭代操作是在背后執行的

為了更直觀地理解流以及 Lambda 在其的應用,我們可以先創建一個菜肴類

public class Dish {
    // 名字
    private String name;
    // 是否素食
    private Boolean vegetarian;
    // 卡路里
    private Integer calories;
    // 類型
    private Type type;

    public Dish(String name, Boolean vegetarian, Integer calories, Type type) {
        this.name = name;
        this.vegetarian = vegetarian;
        this.calories = calories;
        this.type = type;
    }

    // 類型:肉、魚、其他
    public enum Type {
        MEAT, FISH, OTHER
    }

    // Getter and Setter
}

然后用構造函數定義一個菜單 List,好讓我們對其進行流的演示

        List menu = new ArrayList<>();
        // 豬肉:非素食,800卡路里,肉類
        menu.add(new Dish("pork", false, 800, Dish.Type.MEAT));
        // 牛肉:非素食,700卡路里,肉類
        menu.add(new Dish("beef", false, 700, Dish.Type.MEAT));
        // 米飯:素食,359卡路里,其他
        menu.add(new Dish("rice", true, 350, Dish.Type.OTHER));
        // 披薩:素食,550卡路里,其他
        menu.add(new Dish("pizza", true, 550, Dish.Type.OTHER));
        // 對蝦:非素食,350卡路里,魚類
        menu.add(new Dish("prawns", false, 350, Dish.Type.FISH));
        // 三文魚:非素食,450卡路里,魚類
        menu.add(new Dish("salmon", false, 450, Dish.Type.FISH));

接下來我們使用流找出頭三個高熱量菜肴的名字

        List threeHighCaloriesDishNames = menu
                // 從 menu 獲得源
                .stream()
                // Lambda 調用謂詞函數式接口過濾卡路里大于400的高熱量菜肴
                .filter((dish) -> dish.getCalories() > 400)
                // 將過濾結果映射成對應的菜肴名
                .map(Dish::getName)
                // 按照順序選擇三個
                .limit(3)
                // 保存成 List
                .collect(Collectors.toList());

其中兩個 Lambda 對應的是以下的快捷寫法

        // 返回一個判斷卡路里是否高于400的謂詞接口對象
        Predicate dishPredicate = (Dish dish) -> dish.getCalories() > 400;
        // 返回一個映射菜肴名稱的映射接口對象
        Function dishStringFunction = (Dish dish) -> dish.getName();

如果看不懂請回顧上兩章內容。涉及到行為參數化和 Lambda 的多種可簡寫方式。

在這個小小的例子里,有很多概念。我們先是對 menu 調用 stream 方法得到一個流,所以可以稱 menu 為 。它給流提供一個 元素序列,接下來對流進行的一系列 數據處理操作 都會返回另一個流:filter、 map、limit,這樣它們就可以拼接成一條 流水線。最后 collect 操作開始處理流水線,并返回結果。在調用 collect 之前沒有任何結果產生,實際上根本就沒有從 menu 里選擇元素。可以這么說,在流水線里的方法調用都在排隊等待,直到調用 collect。

流與集合

粗略地說,流與集合之間的差異就在于什么時候進行計算。流是在概念上固定的數據結構,其元素則是按需計算的。例如,盡管質數有無窮多個,但我們僅僅需要從流中提取需要的值,而這些值只會按需生成。與此相反,集合想要創建一個包含所有質數的集合,那會計算起來沒完沒了,因為總有新的質數要計算,這樣我們就不能從中取得需要的值。

和迭代器一樣,流只能遍歷一次,遍歷完后我們就可以說這個流被消費掉了。我們可以從源再獲得一個新的流來重新遍歷。

用同一個流遍歷 menu 兩次會拋出異常

        Stream dishStream = menu.stream();
        // 等同于 dishStream.forEach((Dish dish) -> System.out.println(dish));
        dishStream.forEach(System.out::println);
        // java.lang.IllegalStateException: stream has already been operated upon or closed
        // 流已經被操作或關閉
        dishStream.forEach(System.out::println);
外部迭代與內部迭代

集合需要我們手動去做迭代,比如 for-each,這樣被稱為外部迭代。相反,流使用內部迭代。

集合:使用 for-each 循環外部迭代

        List dishNames = new ArrayList<>();
        for (Dish dish : menu) {
            dishNames.add(dish.getName());
        }

流:內部迭代

        List dishNames = menu
                .stream()
                .map(Dish::getName)
                .collect(Collectors.toList());

乍一看好像沒有多大的區別,但是如果考慮到并行處理呢?如果使用外部迭代則需要我們很痛苦地自己去處理并行,而用流則非常簡單,只需要把 stream 換成 parallelStream。

流的使用一般包括三件事:

一個數據源來執行一個查詢

一個中間操作鏈,形成一條流水線

一個終端操作,執行流水線并生成結果

以上便是流的一些基礎知識,下一章會更加深入理解流。

Java 8 實戰 第四章 引入流 讀書筆記

歡迎加入咖啡館的春天(338147322)。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/70217.html

相關文章

  • 《java 8 實戰》讀書筆記 -第四章 引入

    摘要:第四章引入流一什么是流流是的新成員,它允許你以聲明性方式處理數據集合通過查詢語句來表達,而不是臨時編寫一個實現。 第四章 引入流 一、什么是流 流是Java API的新成員,它允許你以聲明性方式處理數據集合(通過查詢語句來表達,而不是臨時編寫一個實現)。就現在來說,你可以把它們看成遍歷數據集的高級迭代器。此外,流還可以透明地并行處理,你無需寫任何多線程代碼。 下面兩段代碼都是用來返回低...

    jeyhan 評論0 收藏0
  • 《Java8實戰》-第四章讀書筆記(引入Stream)

    摘要:內部迭代與使用迭代器顯式迭代的集合不同,流的迭代操作是在背后進行的。流只能遍歷一次請注意,和迭代器類似,流只能遍歷一次。 流(Stream) 流是什么 流是Java API的新成員,它允許你以聲明性方式處理數據集合(通過查詢語句來表達,而不是臨時編寫一個實現)。就現在來說,你可以把它們看成遍歷數據集的高級迭代器。此外,流還可以透明地并行處理,你無需寫任何多線程代碼了!我會在后面的筆記中...

    _ivan 評論0 收藏0
  • nodeJs文件系統(fs)與(stream)

    摘要:異步文件系統不會阻塞程序的執行,而是在操作完成時,通過回調函數將結果返回。 文件系統(File System): 在Node中,文件系統的交互是非常重要的,服務器的本質就是將本地的文件發送給客戶端, Node通過fs模塊來和文件系統進行交互,該模塊提供了一些標準的文件訪問API類打開、讀取、寫入文件、以及與其交互。 要是用fs模塊,首先要從核心模塊中加載; 使用 const fs= ...

    0x584a 評論0 收藏0
  • Java8新特性總覽

    摘要:新特性總覽標簽本文主要介紹的新特性,包括表達式方法引用流默認方法組合式異步編程新的時間,等等各個方面。還有對應的和類型的函數連接字符串廣義的歸約匯總起始值,映射方法,二元結合二元結合。使用并行流時要注意避免共享可變狀態。 Java8新特性總覽 標簽: java [TOC] 本文主要介紹 Java 8 的新特性,包括 Lambda 表達式、方法引用、流(Stream API)、默認方...

    mayaohua 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<