1. 程式人生 > >[瘋狂Java]集合:專門用於聚集操作的一次性集合——Stream(流)

[瘋狂Java]集合:專門用於聚集操作的一次性集合——Stream(流)

1. Java 8新增的Stream特殊集合:

    1) Stream,即流,和之前講過的I/O流並非一種流,是一種特殊的有序、可重複集合,可以往流中放很多元素;

!!它不屬於Collection、Map體系,但是Collection可以轉化成Stream;

    2) 它的特殊之處在於,流專門用於對集合中的元素進行聚集操作(聚集操作泛義上將就是諸如統計操作之類的操作,比如求平均值、最大值/最小值等操作);

    3) 因為流這種結構進行聚集操作有獨特的優勢,其中最大的優勢就是速度快!

    4) 速度快也是用一定的代價換來的——壽命短,通常都是一次性的:比如一個已經放入元素的流,進行完一次球平均值或者找最大最小值的操作之後,流就被消耗掉了,就不能再使用了,要想在統計另外一個值就需要重新建立流、重新往流中放入元素,然後重新統計;

!!因此,Stream的運用場合通常是那種臨時性、一次性的統計,不會頻繁發生的那種統計,在實際應用中,這種情況經常發生,因此Java 8專門推出了Stream;

2. Stream簡介:

    1) Java 8的Stream有多種版本,其中最基礎的根類就是Stream,其中可以存放任何型別的資料(模板類),但不過Java為了方便也實現了各種TypeStream,其中Type支援int、long、double等基本資料型別;

    2) 構造Stream物件:

         i. Java採用生產線模式設計Stream類,即必須先獲取一個Stream物件的生產者,然後用這個生產者來生產Stream物件;

         ii. 所有的Stream類都有一個靜態工具方法builder,可以獲得一個相應Stream類的生產者:static<T> Stream.Builder<T> builder();

         iii. 生產者Builder有兩個方法,一個是add,一個是build,先用add往"流"(此時的流只是一個半成品)中加入一個個元素,加完之後呼叫build方法完成“產品”返回最終成型的Stream流物件:

              a. default Stream.Builder.Builder<T> add(T t);  // 其返回的還是Builder本身,因此可以連續add了,例如builder.add(1).add(2).add(3)....

              b. Stream<T> build();  // 最終生產出成型的Stream物件,連起來就可以這樣子Stream s = builder.add(1).add(2).add(3).build();

         iv. Collection介面提供了一個stream方法,可以用集合中的元素構造一個臨時的Stream物件,因此這樣也可以直接構造出一個流:default Stream Collection.stream();

    3) 構造完Stream物件後就可以呼叫其各種聚集方法進行統計了;

3. Stream聚集操作:

    1) 聚集操作有兩類,一類是中間方法,另一類是末端方法:

        i. 中間方法:進行一定的操作得到(返回)一個新的流(比如每個元素+1得到一個新的流),而這個新的流還可以繼續進行其他聚集操作(沒有被消耗);

        ii. 末端方法:通常都是會計算出一個統計值的方法(比如求平均值、統計總共有多少個元素、求最大/最小值等),這些方法會消耗流,消耗完後流就不能再使用了,想要統計其它東西就必須要重新構造流了!!

    2) 典型的中間方法:

         i. Stream filter(Predicate predicate); // 濾掉流中“不”滿足謂詞條件的,即只保留滿足謂詞條件的元素,返回這個新的流

         ii. TypeStream mapToType(ToTypeFunction mapper); // 將流轉換成一種基本型別的流,其中type支援int、long、double這三種

!ToTypeFunction是一個函式式介面,用來定義每個元素如何轉換成新流中的元素:

public interface ToLongFunction<T> {
    type applyAsType(T value);
}
!!value必定是流中的迭代元素了;

!!示例:Stream s = ....;  IntStream is = s.mapToIntStream(ele -> (String)ele.length());  // 將每個元素替換成其長度形成一個新的流

         iii. Stream peek(Consumer action);  // 觀察流的內容,返回原來的流保持不變,action用來觀察流中的每個元素,該方法主要用來除錯,並不產生實際作用(比如輸出流中的每個值)

         iv. Stream distinct(); // 去重後得到一個新的流,去重使用equals方法做相等比較,該方法不要求先對流進行排序,可以直接亂序去重(而且其演算法也不是先對流進行排序的),因此非常牛逼!

         v. Stream sorted();  // 排序(預設從小到大)得到一個新的流

         vi. Stream limit(long maxSize); // 規定最多允許訪問多少個元素,比如一個流長度為5,而現在你limit(3),那麼count計算數量時返回的就是3,即規定了操作的範圍

    3) 典型的末端方法:末端方法會消耗完整個流,呼叫完之後流宣佈死亡,需要統計其它資訊就得重新建立流了

         i. void forEach(Consumer action); // 遍歷

         ii. Object[] toArray(); // 轉換成相應的陣列,如果是TypeStream那返回的就是Type[]了!

常規的統計方法:

         i. find最小/最大值:

            a. Stream版的:Optional Stream.min | max(Comparator comparator); // Optional<T>代表任意型別,任意型別比較大小必須要規定比較介面Comparator

            b. TypeStream版的:type TypeStream.min | max(); // 簡單很多

         ii. 統計元素個數:long count();

         iii. 檢查是否包含符合謂詞條件的元素:

            a. boolean anyMatch(Predicate predicate); // 是否存在一個滿足謂詞條件的元素

            b. boolean allMatch(Predicate predicate); // 是否全部元素都滿足謂詞條件

            c. boolean noneMatch(Predicate predicate); // 是否全都不滿足謂詞條件

         iv. 獲取第一個元素:Optional findFirst();

4. 示例:

public class Test {
	public static void main(String[] args) {
		
		IntStream is = IntStream.builder().add(50).add(30).add(60).add(30).add(70).add(70).add(10).build();
		is.filter(ele -> ele > 10).distinct().sorted().forEach(System.out::println);
	}
}
!!Lambda表示式列印一個元素可以直接System.out::println,表示列印那個ele迭代元素,最最變態的簡潔!!

相關推薦

[瘋狂Java]集合專門用於聚集操作一次性集合——Stream

1. Java 8新增的Stream特殊集合:     1) Stream,即流,和之前講過的I/O流並非一種流,是一種特殊的有序、可重複集合,可以往流中放很多元素; !!它不屬於Collection、Map體系,但是Collection可以轉化成Stream;     2

【轉載】JAVA多線程讀取、操作List集合

線程 nbsp static 一點 stat lang 素數 param 應用 本文轉載自:http://blog.csdn.net/wang1989cs/article/details/47663565 import java.util.ArrayList; impor

瘋狂java講義多執行緒

第十六章  多執行緒(一)     並行:在同一時刻,有多條指令在多個處理器上同時執行     併發:同一時刻只有一個指令被處理器執行,但多個程序指令快速輪換執行,使得巨集觀好像多個指令在同時執行     作業系統可以同時執行多個任務,每個任務就是程序;程序可以

[瘋狂Java]JDBC載入資料庫驅動、連線資料庫

1. 載入資料庫驅動:     1) 由於Java是一個純面嚮物件語言,任何事物在其中都必須抽象成類或者類物件,資料庫也不例外,JDBC同樣也把資料庫抽象成面向物件的結構;     2) JDBC將整個資料庫驅動器在底層抽象成一個物件(即驅動器物件),所有對資料庫的操作都可

[瘋狂Java]JDBCResultSetMetaData結果集元資料分析

1. 描述ResultSet資訊的資料——ResultSetMetaData:     1) MetaData即元資料,即描述其它資料的資料,因此ResultSetMetaData就是描述ResultSet的元資料;     2) 通常在你對查詢結果不瞭解的情況下可以使用該

[瘋狂Java]SQL子查詢

1. SQL標準對子查詢的定義:     1) 簡單的講就是巢狀select查詢,SQL都支援多層巢狀查詢;     2) 要求記憶體的查詢必須用括號()包起來;     3) 子查詢可以出現的位置:          i. from之後:查詢的實質就是一個臨時的檢視,因此

[瘋狂Java]JDBC資料庫元資料分析

1. 資料庫元資料——有時候並不僅僅需要分析和業務邏輯相關的表,也需要分析當前資料庫的有關資訊:     1) 比如分析當前資料庫中有多少張表、當前共建立了多少外來鍵、多少索引、某個表的結果如何等等;     2) 這些都屬於描述資料庫中資料的資料,稱為元資料;     3

[瘋狂Java]陣列Arrays陣列工具類

1. Arrays工具類簡介:     1) 是Java提供的專門用來運算元組的工具類,裡面有一大堆靜態方法(演算法)來運算元組,低位就相當於C++ STL的<algorithm>庫,只不過Arrays裡面全部都是運算元組的演算法,於此類似的是Collectio

[瘋狂Java]UDP接收發送資料報、獲取接收到的資料報的相關資訊

1. Java的UDP模型:     1) DatagramSocket是UDP的socket,由於它只是個碼頭只能發貨和收貨,因此它就只有兩個方法,一個是send用來發送資料報,一個即使receive用來接收資料報;     2) 由於DatagramSocket只是個碼

[瘋狂Java]SQL常量、變數、運算子、字串匹配運算子like

1. 常量和變數以及運算:     1) SQL中的常量和C語言以及其它語言中的常量定義完全相同,就是一些字面值,比如15、'xyz'就分別是數值型字面值和字串型字面值,它們都屬於常量;     2) 而變數是可以定義在SQL指令碼中的,但是我們平時寫查詢語句中用的最多的變

Java 操作PPT數字簽名新增、檢測、刪除簽名

本文簡要概述如何通過Java程式來處理PPT中的數字簽名,文章主要分三個部分來介紹,即數字簽名的新增、驗證以及刪除。 基本操作思路: 1. 添加簽名:【載入PPT文件】→【添加簽名】→【儲存文件】 2. 檢測簽名:【載入PPT文件】→【判定是否簽名】→【輸出判定結果】 3. 刪除簽名:【載入PPT文件】→【判

python中關於操作時間的方法使用datetime模塊

log time模塊 bsp lib .py nth mon target ear 使用datetime模塊來獲取當前的日期和時間 1 import datetime 2 i=datetime.datetime.now() 3 print ("當前的日期和時間是%

JAVA繼承編譯與運行的關系編譯看左邊,運行看右邊

句子 clas http .com 技術分享 eth com 簡單 images “成員變量,靜態方法看左邊;非靜態方法:編譯看左邊,運行看右邊。” 意思是:當父類變量引用子類對象時(Fu f = new Zi();),在這個引用變量f指向的對象中,他的成員變量和靜態方法

python第三天學習復習,集合set,文件操作,函數普通函數,遞歸,高階函數,字符編碼和解碼

下層 utf-8 只讀 sub pytho bsp for sca move  三元運算  age = 23 #就是if else的簡單寫法 a = age if age < 20 else 25 集合 set #集合是無序切不重復的, #當對列表去重復的時候,

Java常用的八種排序演算法與程式碼實現桶排序、計數排序、基數排序

三種線性排序演算法:桶排序、計數排序、基數排序 線性排序演算法(Linear Sort):這些排序演算法的時間複雜度是線性的O(n),是非比較的排序演算法 桶排序(Bucket Sort)   將要排序的資料分到幾個有序的桶裡,每個桶裡的資料再單獨進行排序,桶內排完序之後,再把桶裡的

Java常用的八種排序演算法與程式碼實現歸併排序法、快速排序法

注:這裡給出的程式碼方案都是通過遞迴完成的 --- 歸併排序(Merge Sort):   分而治之,遞迴實現   如果需要排序一個數組,我們先把陣列從中間分成前後兩部分,然後對前後兩部分進行分別排序,再將排好序的數組合並在一起,這樣整個陣列就有序了   歸併排序是穩定的排序演算法,時間

阿里p8架構師分享Java經典基礎與高階面試36題和答案

19.為什麼集合類沒有實現Cloneable和Serializable介面? 克隆(cloning)或者是序列化(serialization)的語義和含義是跟具體的實現相關的。因此,應該由集合類的具體實現來決定如何被克隆或者是序列化。 20.什麼是迭代器(Iterator)? Itera

如何優化Java程式十進位制轉十六進位制2的31次方以內的正整數

程式碼如下: package com.java; import java.util.Scanner; public class TestTransform {  public static void main(String[] args) {     Scanner

Java常用的八種排序演算法與程式碼實現氣泡排序法、插入排序法、選擇排序法

這三種排序演算法適合小規模資料排序 ---   共同點:基於比較,時間複雜度均為O(n2),空間複雜度均為O(1)(原地排序演算法)   不同點:插入排序和氣泡排序是穩定的排序演算法,選擇排序不是 ---   穩定排序演算法:可以保持數值相等的兩個物件,在排序之

java操作word的方法總結

  這篇部落格是用來總結java操作word的方法,因為我有的一個專案即將要用到java來操作word,所以暫時寫這篇部落格來記錄一下,而且我看了網上很多的資料都沒有發現比較完善的有關java操作word的方法的總結,因此想寫一篇部落格來補充這個方面的不足。(由