Java Stream流詳解——串行版

Stream流——串行版

? Stream流是java8引入的特性,極大的方便了我們對于程序內數據的操作,提高了性能。通過函數式編程解決復雜問題。

1.BaseStream<T,S extense BaseStream<T,S>>

? 他是流處理的基石概念,重點不在于這個接口定義了什么方法,而是它獨特的參數類型。
首先約定好:T——入參類型 S——出參類型
S是繼承于自己的同樣的類型,從而形成一種遞歸,每一次返回的結果類型都是自己或它的子類。這樣做是因為我們在流處理時,不會在原有的流上進行操作,而是形成新的流返回會去。這樣設計免去了類型轉換出錯和增強了靈活性

2.Stream extends BaseStream<T, Stream>

BaseStream有4大子類,我們講一個使用范圍最廣的——Stream
它定義了我們常用的一些方法如
Stream filter (Predicate<? super T> predicate)
這里的Predicate就是一個函數式例如判斷對象是否為空 s->s!=null

中間操作 (Intermediate operations)

無狀態 (Stateless)有狀態 (Stateful)
unordered()distinct() 去重
filter() 過濾元素sorted() 排序
map() 轉換元素類型limit()
mapToInt()skip() 跳過前n個元素
mapToLong()
mapToDouble()
flatMap()
flatMapToInt()
flatMapToLong()
flatMapToDouble()
peek()

結束操作 (Terminal operations)

非短路操作短路操作 (short-circuiting)
forEach()anyMatch()
forEachOrdered()allMatch()
toArray()noneMatch()
reduce() 歸約findFirst()
collect()findAny()
max()
min()
count()

咱們這里通過它的一個實現類ReferencePipeline來舉個例子來體驗一下

List<Integer> numbers = Arrays.asList(2, 1, 3, 8, 5, 6, 7, 4, 9, 10);
List<String> evenNumbers = numbers.stream().map(o->o.toString())//將元素轉為字符串.filter(n -> n.length() == 1)//剔除大于兩位數的元素.sorted()//排序.collect(Collectors.toList());//整合出一個新的流返回System.out.println(evenNumbers);

先定義了一個List,通過.stream()新建一個流管道,函數式編程的好處就是他可以把操作整合到一起,這里的 o->o.toString()和n->n.length()==1會被Java整合為
(o -> o.toString()) -> (n -> n.length() == 1)一個操作鏈
接下來,您是否好奇這個鏈條是如何組裝的,反正我很好奇,let's dive into water

3.ReferencePipeline

在這里插入圖片描述

它繼承了AbstractPipeline,而在其中保存了三個引用,類型都是自己,分別是sourceStage指向第一個Sink(后續展開),接下來就是previousStage和nextStage分別鏈接上下Sink。
下圖給出了具體的流程
在這里插入圖片描述

中間操作是一種爛加載處理,只有當觸發了collect()方法才會真正的調用每個Steam流中的wrapSink方法去處理數據。之后調用sort()進行排序。我們來具體看一個方法是如何處理的

 public final <R> Stream<R> map(Function<? super P_OUT, ? extends R> mapper) {Objects.requireNonNull(mapper);return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE,StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {@OverrideSink<P_OUT> opWrapSink(int flags, Sink<R> sink) {return new Sink.ChainedReference<P_OUT, R>(sink) {@Overridepublic void accept(P_OUT u) {downstream.accept(mapper.apply(u));

在ReferencePipeline中它定義三個靜態內部類——StatelessOp,StatafulOp,Head。先是對函數式判空,然后返回一個無狀態流。關鍵在于它內部定義的opWrapSinlk通過返回一個Sink類并在其中定義了具體的操作accept()。然后調用函數式,并通過accept()觸發下游Stream進行進一步處理。

4.Sink

抽象的來講,上面所說的ReferencePipeline就像是流水線上不停流動的傳輸帶,而真正在加工物品的就是我們的Sink類

在這里插入圖片描述

這里的Consumer接口就是我們將不同的流處理函數式拼接起來的關鍵

public interface Consumer<T> {void accept(T t);default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}
}

andThen()方法,首先是自己調用自己的accept(),再調用下游的accept()
像我們前面寫到的例子,map(o->o.toString)和filter(n->n.length)中的參數就是一個Consumer

5.歸約

我們將最后一步collect()定義為歸約,將流中的所有元素歸約為一個最終的結果。
它通過操作一個Collector進行操作,包含三個步驟
累加(accumulation):將流中的每個元素依次累加到一個容器中。
合并(combining):如果存在并行流,多個部分的結果需要合并。
完成(finishing):在所有元素處理完后,生成最終的結果。

public interface Collector<T, A, R> {Supplier<A> supplier(); // 提供一個容器,容器類型是 ABiConsumer<A, T> accumulator(); // 累加器,負責將元素添加到容器BinaryOperator<A> combiner(); // 合并器,用于并行處理時合并多個容器Function<A, R> finisher(); // 結果轉換器,返回最終的結果Set<Collector.Characteristics> characteristics(); // 一些特征,指示這個 Collector 是否具有某些優化特性
}

例如我們最常用的toList()將流中的所有元素收集到一個Lsit中。

 public static <T>Collector<T, ?, List<T>> toList() {return new CollectorImpl<>(ArrayList::new, List::add,(left, right) -> { left.addAll(right); return left; },CH_ID);}

ArrayList::new,返回一個List容器,通過List::add方法添加進入容器,后續處理并行流。

以下是關于 Java Stream API 中 collect 歸約操作的表格,其中總結了常見的歸約操作、作用說明及示例:

歸約操作作用說明示例代碼
toList()將流中的元素收集到一個 List 中。List<String> result = names.stream().collect(Collectors.toList());
toSet()將流中的元素收集到一個 Set 中,自動去重。Set<String> result = names.stream().collect(Collectors.toSet());
joining()將流中的元素連接成一個字符串,支持指定分隔符、前綴和后綴。String result = names.stream().collect(Collectors.joining(", ", "[", "]"));
groupingBy()根據某個條件將流中的元素分組,返回一個 MapMap<Integer, List<String>> groupedByLength = names.stream().collect(Collectors.groupingBy(String::length));
partitioningBy()將流中的元素分成兩組,通常用于二元分類。Map<Boolean, List<String>> partitioned = names.stream().collect(Collectors.partitioningBy(name -> name.length() > 3));
summarizingInt()對流中的元素進行統計,返回 IntSummaryStatistics,包括計數、求和、最小值、最大值、平均值等。IntSummaryStatistics stats = names.stream().collect(Collectors.summarizingInt(String::length));
reducing()對流中的元素進行歸約操作(例如累加、求最大值等),返回一個單一結果。Optional<String> result = names.stream().collect(Collectors.reducing((s1, s2) -> s1.length() > s2.length() ? s1 : s2));
toMap()將流中的元素根據某個鍵值映射規則收集到一個 Map 中。Map<Integer, String> map = names.stream().collect(Collectors.toMap(String::length, name -> name));
   | 將流中的元素根據某個鍵值映射規則收集到一個 `Map` 中。        | `Map<Integer, String> map = names.stream().collect(Collectors.toMap(String::length, name -> name));` |

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64222.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64222.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64222.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

el-backtop(返回頂部)

案例&#xff1a; <el-backtop target".app-main"><svg-icon icon-class"backtop" size"24px" /></el-backtop>

探秘“香水的 ChatGPT”:AI 開啟嗅覺奇幻之旅!

你沒有看錯&#xff0c;AI也能聞到味道了&#xff01;這是一家名為Osmo公司公布的信息&#xff0c;他們成功創造出了由AI生成的李子味道&#xff0c;快跟著小編一探究竟吧~ 【圖片來源于網絡&#xff0c;侵刪】 Osmo公司的這項技術&#xff0c;通過分析香味的化學成分和人類嗅…

Vue3入門(9)

1. 【 replace屬性】 作用&#xff1a;控制路由跳轉時操作瀏覽器歷史記錄的模式。 瀏覽器的歷史記錄有兩種寫入方式&#xff1a;分別為push和replace&#xff1a; - push是追加歷史記錄&#xff08;默認值&#xff09;。 - replace是替換當前記錄。 . 開啟replace模式&#xff…

第十九章 C++ 日期 時間

C 日期 & 時間 C 標準庫沒有提供所謂的日期類型。C 繼承了 C 語言用于日期和時間操作的結構和函數。為了使用日期和時間相關的函數和結構&#xff0c;需要在 C 程序中引用 <ctime> 頭文件。 有四個與時間相關的類型&#xff1a;clock_t、time_t、size_t 和 tm。類型…

電子配件行業的未來之路:產品說明書數字化轉型的力量

在科技飛速發展的今天&#xff0c;電子配件行業作為科技創新的前沿陣地&#xff0c;正經歷著前所未有的變革。從智能手機、平板電腦到智能穿戴設備&#xff0c;各種新型電子配件層出不窮&#xff0c;極大地豐富了人們的生活。然而&#xff0c;隨著產品種類的增多和功能的復雜化…

強化學習方法分類詳解

強化學習方法分類詳解 引言 強化學習&#xff08;Reinforcement Learning, RL&#xff09;是一種通過智能體與環境互動來學習如何做出最佳決策的方法。根據不同的優化中心、策略特性、環境模型、獎勵函數、動作空間類型以及行為策略和目標策略的一致性&#xff0c;RL可以分為…

RockyLinux介紹及初始化

文章目錄 一、背景二、下載 RockyLinux9 鏡像三、環境初始化四、安裝 Docker 環境 一、背景 這里講一個小故事&#xff1a; 我們都知道Linux 內核是由芬蘭計算機科學家林納斯托瓦茲 (Linus Torvalds) 于 1991 年首次開發的&#xff0c;隨后有一個非常重要的公司RetHat成立&am…

AWS、Google Cloud Platform (GCP)、Microsoft Azure、Linode和 桔子數據 的 價格對比

要對比 AWS、Google Cloud Platform (GCP)、Microsoft Azure、Linode 和 桔子數據 的 價格&#xff0c;我們需要先了解每個平臺的定價模型、服務類型以及不同服務之間的價格差異。以下是根據各個平臺常見服務&#xff08;如計算實例、存儲、數據傳輸等&#xff09;做的一個 簡化…

OpenCV相機標定與3D重建(36)計算兩幅圖像之間基本矩陣(Fundamental Matrix)的函數findFundamentalMat()的使用

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 從兩幅圖像中的對應點計算基本矩陣。 cv::findFundamentalMat 是 OpenCV 中用于計算兩幅圖像之間基本矩陣&#xff08;Fundamental Matrix&#…

Vscode + gdbserver遠程調試開發板指南:

本章目錄 步驟環境準備網絡配置vscode配置步驟 (全圖示例)開發板配置開始調試注意: 每次斷開之后&#xff0c;開發板都需要重新啟動gdbserver才可調試。 參考鏈接: 步驟 環境準備 將交叉編譯鏈路徑加入$PATH變量&#xff1a;確保系統能夠找到所需的工具。 export PATH$PATH:/p…

對外發PDF設置打開次數

在線 Host PDF 文件并對鏈接進行限制——保障文件安全的最佳解決方案 在數字化辦公和遠程協作日益普及的今天&#xff0c;如何安全高效地分享 PDF 文件成為許多用戶關注的重點。MaiPDF 作為一款功能強大的在線工具&#xff0c;不僅支持在線 host PDF 文件&#xff0c;還提供多…

VS2022 中的 /MT /MTd /MD /MDd 選項

我們有時編譯時,需要配置這個 運行庫,指定C/C++運行時庫的鏈接方式。 如下圖 那么這些選項的含義是什么? /MT:靜態鏈接多線程庫 /MT選項代表“Multi-threaded Static”,即多線程靜態庫。選擇此選項時,編譯器會從運行時庫中選擇多線程靜態連接庫來解釋程序中的代碼,…

MacOS下TestHubo安裝配置指南

TestHubo是一款開源免費的測試管理工具&#xff0c; 下面介紹MacOS私有部署的安裝與配置。TestHubo 私有部署版本更適合有嚴格數據安全要求的企業&#xff0c;支持在本地或專屬服務器上運行&#xff0c;以實現對數據和系統的完全控制。 1、Mac 服務端安裝 Mac安裝包下載地址&a…

Windows 11 配置gym、mujoco、mujoco-py環境教程

Windows 11 配置gym、mujoco、mujoco-py環境教程 整理了windows11系統安裝mujoco、mujoco_py、gym的教程以及報錯解決方法。 環境版本 mujoco-py-2.1.2.14 mujoco210 gym==0.23.1 python 3.9.16 pytorch 1.12.1+cu113 mujoco安裝 1. 在Github中下載mujoco210壓縮包 G…

Java重要面試名詞整理(五):Redis

文章目錄 Redis高級命令Redis持久化RDB快照&#xff08;snapshot&#xff09;**AOF&#xff08;append-only file&#xff09;****Redis 4.0 混合持久化** 管道&#xff08;Pipeline&#xff09;**StringRedisTemplate與RedisTemplate詳解**Redis集群方案gossip腦裂 Redis LuaR…

Amazon Bedrock 實踐 - 利用 Llama 3.2 模型分析全球糖尿病趨勢

黃浩文 資深開發者布道師 亞馬遜云科技 擁有電信、互聯網以及云計算等行業超過 20 年的豐富經驗&#xff0c;曾任職于微軟、Sun 和中國電信。他目前專注于生成式 AI、大型語言模型 (LLM)、機器學習和數據科學等領域的技術內容創作和實踐分享&#xff0c;致力于賦能全球開發者。…

期權懂|如何計算期權賣方平倉后的盈利?

錦鯉三三每日分享期權知識&#xff0c;幫助期權新手及時有效地掌握即市趨勢與新資訊&#xff01; 如何計算期權賣方平倉后的盈利&#xff1f; 期權賣方平倉后的盈利計算涉及多個因素&#xff0c;包括期權的交易價格、平倉價格以及權利金的變動等。 交易價格&#xff1a;期權賣…

【連續學習之VCL算法】2017年論文:Variational continual learning

1 介紹 年份&#xff1a;2017 期刊&#xff1a; arXiv preprint Nguyen C V, Li Y, Bui T D, et al. Variational continual learning[J]. arXiv preprint arXiv:1710.10628, 2017. 本文提出的算法是變分連續學習&#xff08;Variational Continual Learning, VCL&#xf…

多視圖 (Multi-view) 與多模態 (Multi-modal)

多視圖 (Multi-view) 與多模態 (Multi-modal) 是兩種不同的數據處理方式&#xff0c;它們在機器學習和數據分析中有著重要的應用。盡管這兩者有一些相似之處&#xff0c;但它們關注的角度和處理方法有所不同。 多視圖 (Multi-view) 定義&#xff1a;多視圖指的是同一數據對象…

MySQL 性能瓶頸,為什么 MySQL 表的數據量不能太大?

MySQL的性能瓶頸(為什么MySQL有幾萬的qps,怎么來的?性能分析 為什么 MySQL 表不能太大網上大部分人的說法:問題的關鍵: B樹層數對查詢性能的影響到底有多大? 是什么導致的 MySQL 查詢緩慢?如何解決: MySQL的性能瓶頸(為什么MySQL有幾萬的qps,怎么來的? 一個全表掃描的查詢…