java8學習筆記-Stream流

JDK1.8新增了Stream類,從而把函數式編程的風格引入到Java語言中,Stream類的API提供了強大的功能,使用Stream后,可以寫出更加強大,更加簡潔的代碼

首先,Stream流有一些特性:

  1. Stream流不是一種數據結構,不保存數據,它只是在原數據集上定義了一組操作。
  2. 這些操作是惰性的,即每當訪問到流中的一個元素,才會在此元素上執行這一系列操作。
  3. Stream不保存數據,故每個Stream流只能使用一次。

關于應用在Stream流上的操作,可以分成兩種:Intermediate(中間操作)和Terminal(終止操作)。中間操作的返回結果都是Stream,故可以多個中間操作疊加;終止操作用于返回我們最終需要的數據,只能有一個終止操作。至于哪些方法是中間操作,哪些方法是終止操作,我們一會兒再說。

使用Stream流,可以清楚地知道我們要對一個數據集做何種操作,可讀性強。而且可以很輕松地獲取并行化Stream流,不用自己編寫多線程代碼,可以讓我們更加專注于業務邏輯。

默認情況下,從有序集合、生成器、迭代器產生的流或者通過調用Stream.sorted產生的流都是有序流,有序流在并行處理時會在處理完成之后恢復原順序。unordered()方法可以解除有序流的順序限制,更好地發揮并行處理的性能優勢,例如distinct將保存任意一個唯一元素而不是第一個,limit將保留任意n個元素而不是前n個。

流的常用生成方法

Collection接口的stream()或parallelStream()方法

parallelStream()是并行方法,parallelStream()不一定比stream()快(需要開啟線程,線程競爭),而且parallelStream()是線程不安全的,所以使用parallelStream()要綜合考量,測試百萬數據的List<String> 的System.out.println(),stream()依舊比parallelStream()要快

        List<Integer> list = new ArrayList();Random random = new Random();for (int i = 0; i < 100000; i++) {list.add(random.nextInt());}Instant start = Instant.now();
//        list.stream().forEach(System.out::print); //193毫秒list.parallelStream().forEach(System.out::print);//275毫秒Instant end = Instant.now();System.out.println("");System.out.println("_______________________________________________________________________");System.out.println("end:" + end.toEpochMilli());System.out.println("start:" + start.toEpochMilli());System.out.println("time:" + (end.toEpochMilli() - start.toEpochMilli()));

靜態的Stream.of()、Stream.empty()方法

        List<Integer> list = new ArrayList();Random random = new Random();for (int i = 0; i < 100000; i++) {list.add(random.nextInt());}Instant start = Instant.now();
//        Stream.of(list).forEach(System.out::println); //71毫秒Stream.empty().forEach(System.out::println);//37毫秒
//        list.stream().forEach(System.out::print); //193毫秒
//        list.parallelStream().forEach(System.out::print);//275毫秒Instant end = Instant.now();System.out.println("");System.out.println("_______________________________________________________________________");System.out.println("end:" + end.toEpochMilli());System.out.println("start:" + start.toEpochMilli());System.out.println("time:" + (end.toEpochMilli() - start.toEpochMilli()));

Arrays.stream(array, from, to)

包前不包后

        int[] arr = {1, 3, 2, 4, 55, 64, 98, 23};Arrays.stream(arr, 1, 3).forEach(System.out::println); 

流的常用Intermediate方法(中間操作)

filter(Predicate) 將結果為false的元素過濾掉

        int[] arr = {1, 3, 2, 4, 55, 64, 98, 23};//過濾單數保留雙數Arrays.stream(arr).filter(item->(item & 1) == 0).forEach(System.out::println);

map(fun) 轉換元素的值,可以用方法引元或者lambda表達式

        int[] arr = {1, 3, 2, 4, 55, 64, 98, 23};//filter過濾單數保留雙數//map將剩余元素除以2Arrays.stream(arr).filter(item->(item & 1) == 0).map(item -> item / 2).forEach(System.out::println);

flatMap(fun) 若元素是流,將流攤平為正常元素,再進行元素轉換

簡單點描述就是嵌套的集合扁平化

比如集合里面包含集合/數組?

        List<List<String>> list = Arrays.asList(Arrays.asList("A", "B"),Arrays.asList("C", "D"),Arrays.asList("E", "E"));// 使用 flatMap 扁平化列表List<String> collect = list.stream().flatMap(List::stream).collect(Collectors.toList());System.out.println(collect); //[A, B, C, D, E, E]

或者集合里面本身沒有集合/數組但是可以操作(字符串切割)變成集合/數組

        List<Person> list = Arrays.asList(new Person("張三", "1,2,3"),new Person("李四", "2,3"),new Person("王五", "2,4"));Set<Object> collect = list.stream().flatMap(person -> Arrays.stream(person.getHobbies().split(","))).collect(Collectors.toSet());System.out.println(collect);

limit(n) 保留前n個元素 常配合排序使用

        int[] arr = {1, 3, 2, 4, 55, 64, 98, 23};Arrays.stream(arr).limit(2).forEach(System.out::print); //13

skip(n) 跳過前n個元素

        int[] arr = {1, 3, 2, 4, 55, 64, 98, 23};Arrays.stream(arr).skip(6).forEach(System.out::print); //9823

distinct() 剔除重復元素

        int[] arr = {1, 2, 2, 4, 2};Arrays.stream(arr).distinct().forEach(System.out::print); //124

sorted() ,sorted(Comparator) 將Comparable元素的流排序

        int[] arr = {1, 2, 2, 4, 2};Arrays.stream(arr).sorted().forEach(System.out::print); //12224
        List<Person> list = Arrays.asList(new Person("張三", 18,"2,3"),new Person("李四", 14,"2,3"),new Person("王五", 21,"2,4"));//根據年齡排序 reversed()倒序操作list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).forEach(System.out::println);

peek(fun) 流不變,但會把每個元素傳入fun執行,可以用作調試

可以理解為沒有返回結果的forEach()

        List<Person> list = Arrays.asList(new Person("張三", 18,"2,3"),new Person("李四", 14,"2,3"),new Person("王五", 21,"2,4"));//根據年齡排序 reversed()倒序操作list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).peek(item->{item.setAge(item.getAge() + 1);}).peek(item->{item.setAge(item.getAge() + 1);}).peek(item->{item.setAge(item.getAge() + 1);}).forEach(System.out::println);結果:
Person(name=王五, age=24, hobbies=2,4)
Person(name=張三, age=21, hobbies=2,3)
Person(name=李四, age=17, hobbies=2,3)

流的Terminal方法(終結操作)

max(Comparator)

min(Comparator)

count()

findFirst() 返回第一個元素

findAny() 返回任意元素

anyMatch(Predicate) ,allMatch(Predicate) ,noneMatch(Predicate)

anyMatch(Predicate)任意元素匹配時返回true

所有元素匹配時返回true

沒有元素匹配時返回true

reduce(fun) 從流中計算某個值,接受一個二元函數作為累積器,從前兩個元素開始持續應用它,累積器的中間結果作為第一個參數,流元素作為第二個參數

reduce(a, fun) a為幺元值,作為累積器的起點

reduce(a, fun1, fun2)

iterator()

forEach(fun)

forEachOrdered(fun) 可以應用在并行流上以保持元素順序

toArray()

toArray(T[] :: new) 返回正確的元素類型

collect(Collector)

collect(fun1, fun2, fun3)

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

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

相關文章

Flutter開發 dart語言基本語法

特點 Dart語言支持JIT與AOT。 Dart語言采用單線程模型。 Dart語言是強類型編程語言&#xff0c;但是允許弱類型語言式編程。 基本語法 1.變量和常量 變量 var、object、dynamic關鍵字或數據類型顯式聲明變量。 命名規則&#xff1a; 變量名稱必須由數字、字母、下劃線或$組成&a…

SpringBoot:基于 Redis 自定義注解實現后端接口防重復提交校驗(冪等操作)

SpringBoot&#xff1a;基于 Redis 自定義注解實現后端接口防重復提交校驗&#xff08;冪等操作&#xff09;可基于 時間間隔 和 用于冪等判斷的參數名稱 實現防重復提交校驗 客戶端發送請求 ↓ [Spring Boot 應用入口]↓ ┌─────────────────────────…

【語音技術】意圖與語料

目錄 1. 意圖 1.1. 意圖分類 1.1.1 入口意圖&#xff08;Entry Intent&#xff09; 1.1.2 對話意圖&#xff08;Dialog Intent&#xff09; 1.2. 意圖類型切換操作步驟 2. 語料 2.1 語料分類詳解 2.2 語料編寫規范詳解 2.3 標簽符號深度說明 3. 詞槽 3.1 符類型要求 …

【MySQL集群架構與實踐5】使用Docker實現水平分片

目錄 一. 在Docker中安裝ShardingSphere 二. 實踐&#xff1a;水平分片 2.1 應用場景 2.2 架構圖 2.3 服務器規劃 2.4 創建server-user容器 2.5 創建server-order0和server-order1容器 2.6.日志配置 2.7 數據節點配置 2.8.測試數據節點 2.8.1.測試server_order0.t_or…

視覺圖像處理中級篇 [1]—— 彩色照相機的效果與預處理

在工業檢測中&#xff0c;黑白相機雖應用廣泛&#xff0c;但在應對顏色差異檢測時往往力不從心。彩色照相機憑借其對色彩信息的精準捕捉&#xff0c;成為復雜場景下的理想選擇&#xff0c;而預處理技術則進一步釋放了其性能潛力。一、彩色照相機的效果檢查蓋子上的金色標簽可以…

使用 BERT 的 NSP 實現語義感知切片 —— 提升 RAG 系統的檢索質量

在構建 Retrieval-Augmented Generation&#xff08;RAG&#xff09;系統時&#xff0c;文檔的切片方式至關重要。我們需要將長文本切分成合適的段落&#xff08;chunks&#xff09;&#xff0c;然后存入向量數據庫進行召回。如果切得太粗&#xff0c;會丟失上下文細節&#xf…

使用STM32CubeMX生成的STM32CubeIDE工程在更改工程名后編譯失敗問題解決

0 問題描述 使用STM32CubeMX生成STM32CubeIDE工程,然后使用STM32CubeIDE改名后編譯提示如下錯誤: 1 問題原因及解決辦法 1.1 問題原因 原因在于更名后STM32CubeIDE沒有自動更新引用關系,這是因為我們使用STM32CubeMX生成代碼時沒有勾選在根目錄下生成: 取消勾選在根目…

8月3日星期日今日早報簡報微語報早讀

8月3日星期日&#xff0c;農歷閏六月初十&#xff0c;早報#微語早讀。1、廣西防城港&#xff1a;奔馳女司機身份已查清&#xff0c;結果將統一對外發布&#xff1b;2、陳藝文、陳佳包攬游泳世錦賽女子跳水三米板金銀牌&#xff1b;3、九省份保險業已賠付暴雨災害損失5.2億元&am…

wxPython 實踐(六)對話框

wxPython 實踐&#xff08;一&#xff09;概述 wxPython 實踐&#xff08;二&#xff09;基礎控件 wxPython 實踐&#xff08;三&#xff09;頁面布局 wxPython 實踐&#xff08;四&#xff09;事件響應 wxPython 實踐&#xff08;五&#xff09;高級控件 wxPython 實踐&#x…

MATLAB科研數據可視化技術

互聯網的飛速發展伴隨著海量信息的產生&#xff0c;而海量信息的背后對應的則是海量數據。如何從這些海量數據中獲取有價值的信息來供人們學習和工作使用&#xff0c;這就不得不用到大數據挖掘和分析技術。數據可視化分析作為大數據技術的核心一環&#xff0c;其重要性不言而喻…

文明存續的時間博弈:論地球資源枯竭臨界期的技術突圍與行動緊迫性

摘要當地球資源消耗以指數級速度逼近生態承載力極限&#xff0c;人類文明正面臨“存續還是消亡”的終極抉擇。本文基于地球資源枯竭的實證數據與技術突破的可行性分析&#xff0c;揭示文明存續的時間窗口已進入不可逆臨界期&#xff08;2040-2070年&#xff09;&#xff0c;論證…

Elasticsearch 8.19.0 和 9.1.0 中 LogsDB 和 TSDS 的性能與存儲改進

作者&#xff1a;來自 Elastic Martijn Van Groningen 探索 TSDS 和 LogsDB 的最新增強功能&#xff0c;包括優化 I/O、提升合并性能等。 Elasticsearch 帶來了許多新功能&#xff0c;幫助你為你的使用場景構建最佳搜索解決方案。通過我們的示例筆記本深入學習&#xff0c;開始…

cs336之注意pytorch的tensor在哪里?(assert的使用)

問題 記住&#xff1a;無論何時你在pytorch中有一個張量tensor&#xff0c;你應該始終問一個問題&#xff1a;它當前位于哪里&#xff1f; 注意它在CPU還是在GPU中。要判斷它在哪里&#xff0c;可以使用python的assert斷言語句。 assert斷言 在 Python 中&#xff0c;assert 是…

Mysql 分區表

分區表是將一張表分成多張獨立子表&#xff0c;每個子表是一個區&#xff0c;目的是提高查詢效率。 從 server 層來看&#xff0c;只有一張表。但是從引擎層來看&#xff0c;是多張表&#xff0c;對應多個.idb文件。引擎層訪問數據只訪問特定分區表&#xff0c;也只對特定分區表…

Makefile 入門與實踐指南

Makefile 是用于 make 工具的配置文件&#xff0c;它定義了如何編譯和鏈接你的項目&#xff0c;讓構建過程自動化。一、核心概念 make 的核心思想是 “目標”&#xff08;Target&#xff09; 和 “依賴”&#xff08;Dependencies&#xff09;&#xff1a; 目標 (Target)&#…

分布式微服務--Nacos作為配置中心(補)關于bosststrap.yml與@RefreshScope

一、關于bosststrap.yml? bootstrap.yml 和 application.yml 的區別對比項bootstrap.ymlapplication.yml加載時機優先于 application.yml 加載&#xff08;啟動早期&#xff09;程序初始化完成后加載主要用途設置應用的外部配置源、注冊中心信息等設置應用內部配置&#xff0c…

[Qt]QString 與Sqlite3 字符串互動[漢字不亂碼]

環境&#xff1a;Qt C&#xff08;msvc c&#xff09;1.將與數據庫交互的代碼文件編碼轉換為utf-8-bom編碼&#xff0c;&#xff08;可使用notepad 進行轉換&#xff09;2.在代碼文件頭文件中加上下面代碼。//vs2010 版本是 1600 #if defined(_MSC_VER) && (_MSC_VER &…

SpringBoot啟動項目詳解

SpringBoot 的啟動過程是一個整合 Spring 核心容器、自動配置、嵌入式服務器等功能的復雜流程&#xff0c;核心目標是 “簡化配置、快速啟動”。下面從入口類開始&#xff0c;逐步拆解其詳細啟動步驟&#xff1a;一、啟動入口&#xff1a;SpringBootApplication與main方法Sprin…

PCB 控深槽如何破解 5G 基站 120℃高熱魔咒?

5G 基站在高頻通信下的功耗較 4G 基站提升 3-4 倍&#xff0c;射頻模塊、電源單元等核心部件的工作溫度常突破 120℃&#xff0c;遠超設備安全閾值&#xff08;≤85℃&#xff09;&#xff0c;形成制約通信穩定性的 “高熱魔咒”。印制線路板&#xff08;PCB&#xff09;作為熱…

NEXT.js 打包部署到服務器

在網上查了一下&#xff0c;記錄一下1.首先執行打包命令&#xff0c;我這個項目是用的pnpm&#xff0c;可以根據項目需求使用 npm 或者別的pnpm run build2.打包完成后會有一個 .next 的文件夾&#xff0c;需要把下圖的這些文件放到服務器。服務器需要有node環境之后就需要執行…