逸學java【初級菜鳥篇】9.3 Stream流

hi,我是逸塵,一起學java吧


得益于Lambda所帶來的函數式編程,引入了一個全新的Stream流概念(就是都基本使用lambda的形式)。

流處理

我們首先理解什么是流處理,它類似于sql語句,可以執行非常復雜的過濾,映射,查找,收集等功能,且代碼很少,但是可讀性不高。字如其名,它的處理如同流淌的水一樣,或者可以理解為流水線一樣。

Stream流

Stream流也是流處理的一種,大多數流處理都是在Stream接口處理的,它是一個泛接口,所以它可以操作的元素是任意對象,他的操作可以用lambda去書寫(推薦)。

生成Stream流

Stream操作集合和數組的第一步是得到(生成)Stream流。

在Collection接口默認方法是stream()生成流。

?在數組中使用Arrays.stream(數組) /或Stream.of(數組);

?中間操作方法

其次我們就可以使用中間操作來處理這些元素對象。

這里舉出一些常見的API

  • forEach : 逐一處理(遍歷)
  • count:統計個數
  • filter : 過濾元素 【數據過濾】
  • distinct:去除重復元素?【數據過濾】
  • limit : 取前幾個元素?【數據過濾】
  • skip : 跳過前幾個?【數據過濾】
  • map : 加工方法?【數據映射】
  • allMatch:判斷流中的元素是否會全部符合某一個條件?【數據查找】
  • concat:合并流

終結操作方法

終結操作方法調用以后流就無法使用了它是流的最后一個過程。

常見的有API有

單獨保存的操作方法

  • collect() 方法配合collectors類將流的結果進行保存

處了stream流本身的方法我們還有兩個可以協助流操作的類

Collectors類

collectors是一個收集器類,可以將Stream流對象進行封裝,歸集,分組,是數據的收集,篩選出特殊的數據,可以復雜的統計。

1.toList()將流元素封裝到List集合 toSet()?toMap()類似

2.toCollection(Supplier<C> collectionFactory)?將流中的元素收集到指定類型的集合中的方法

即一個類型為?Supplier<C>?的函數式接口,其中?C?是要創建的集合類型。例如,如果我們想要創建一個?LinkedList?集合,可以這樣使用該方法:?

List<Integer> list = Stream.of(1, 2, 3, 4, 5).collect(Collectors.toCollection(LinkedList::new));

3.groupingBy(Function<? super T, ? extends K> classifier)?

  • 一個函數式接口?classifier,表示如何對流中的元素進行分類。

例如,我們有一個字符串列表,并希望按照字符串長度分組:

List<String> list = Arrays.asList("apple", "banana", "peach", "grape","pear");
Map<Integer, List<String>> map = list.stream().collect(Collectors.groupingBy(String::length));

?在上面的代碼中,我們使用 String::length 函數式接口將字符串轉換為它的長度,并將其作為分類鍵。運行結果如下:

{4=[pear], 5=[apple, peach,grape], 6=[banana]}

需要注意的是,groupingBy() 方法返回的是一個 Map 對象,其中鍵是分類鍵.

Collectors.groupingBy() 方法還提供了第二個參數 downstream,用于進一步對分組的結果進行處理。例如,我們可以使用 Collectors.counting() 方法統計每個分組中元素的數量:

Map<Integer, Long> map = list.stream().collect(Collectors.groupingBy(String::length, Collectors.counting()));

上面的代碼中,我們使用 Collectors.counting() 方法作為 downstream 參數,統計了每個分組中元素的數量,并將結果封裝為 Long 類型。運行結果如下:

{4=1, 5=3, 6=1}

4.toConcurrentMap

將流中的元素收集到一個并發?Map?中的方法

ConcurrentMap<Integer, String> concurrentMap = Stream.of("a", "b", "c").collect(Collectors.toConcurrentMap(String::length,Function.identity()));

在上面的例子中,我們使用 toConcurrentMap() 方法創建了一個并發 Map,它將字符串的長度作為鍵,字符串本身作為值。具體來說,這個方法接受兩個參數:

一個函數式接口 keyMapper,表示如何將流中的元素轉換成鍵;
一個函數式接口 valueMapper,表示如何將流中的元素轉換成值。
對于上述例子中的流,String::length 函數式接口將字符串轉換成它的長度,而 Function.identity() 函數式接口則將字符串映射成它本身。因此得到的結果為:

{1=a, 2=b, 3=c}

?5.以及averagingDouble計算元素平均值,maxBy返回符合條件的最大值,joining()按順序將元素連接成一個String類型數據,counting()統計個數等等

optional類

這是一個容器類

它的主要功能是針對NullpointerException空指針異常做處理,可以保證保存的值不為null。

of()返回一個value值等于參數的optional實例

ofNullable()是返回一個value值等于非null參數的optional實例

filter()是給定條件值匹配

empty()是靜態方法,返回一個空值的optional實例

案例?

我們上面的中間操作,其實是對我們的數據源進行加工。

這里我們簡單做了一個去重????????

package com.yd.yc;import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class Thirteen {public static void main(String[] args) {List<Integer> list = Arrays.asList(6,88,4,5,22,22,6,66,7);//原數據printeach(list);//獲取stream,去重,收集器類重新封裝List<Integer> collect = list.stream().distinct().collect(Collectors.toList());printeach(collect);}//遍歷方法private static void printeach(List<Integer> list) {System.out.println("集合內容"+list);//逐一處理(遍歷)里面是lambdalist.stream().forEach(n-> System.out.println(n+""));}
}

某個公司的部門,分為開財務部門和開發部門,現在需要進行月中數據結算。

創建一張員工

部門姓名年齡月工資性別
開發部張三2815000
開發部李四3520000
開發部王五2918000
財務部趙六3316000
財務部劉七3017000
財務部陳八2714000

對應的是我們的員工實體類

public class Employee {  private String name;  private int age;  private double monthlySalary;  private String gender;  private String department;  public Employee(String name, int age, double monthlySalary, String gender, String department) {  this.name = name;  this.age = age;  this.monthlySalary = monthlySalary;  this.gender = gender;  this.department = department;  }  public String getName() {  return name;  }  public int getAge() {  return age;  }  public double getMonthlySalary() {  return monthlySalary;  }  public String getGender() {  return gender;  }  public String getDepartment() {  return department;  }  
}

分別篩選出2個部門的最高工資的員工信息,封裝成優秀員工對象topperformer

方案A

package com.yd.yc;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class EmployeeTest {public static void main(String[] args) {Employee employee1 = new Employee("張三", 28, 15000, "男", "開發部");Employee employee2 = new Employee("李四", 35, 20000, "女", "開發部");Employee employee3 = new Employee("王五", 29, 18000, "男", "開發部");Employee employee4 = new Employee("趙六", 33, 16000, "女", "財務部");Employee employee5 = new Employee("劉七", 30, 17000, "男", "財務部");Employee employee6 = new Employee("陳八", 27, 44000, "女", "財務部");//測試//System.out.println(employee1.getName());  // 輸出:張三//System.out.println(employee2.getMonthlySalary());  // 輸出:20000.0ArrayList<Employee> employeeList = new ArrayList<>();employeeList.add(employee1);employeeList.add(employee2);employeeList.add(employee3);employeeList.add(employee4);employeeList.add(employee5);employeeList.add(employee6);//A方案//filter是過濾找到符合條件的元素//Collectors.maxBy去返回符合條件的最大值,Comparator.comparing(param),param : 這個參數是Function函數式對象,默認大,Comparator.reverseOrder()默認倒序Optional<Employee> result = employeeList.stream().filter(e -> "開發部".equals(e.getDepartment())).collect(Collectors.maxBy(Comparator.comparing(Employee::getMonthlySalary)));//返回一個實體類對象Employee employee = result.get();System.out.println(employee.getName());//第二種寫法Employee  resultOne= employeeList.stream().filter(e -> "財務部".equals(e.getDepartment())).max((o1, o2) -> Double.compare(o1.getMonthlySalary(), o2.getMonthlySalary())).get();//必須重寫toString才可以有內容System.out.println(resultOne);System.out.println(resultOne.getMonthlySalary());//包裝在一個優秀員工里List<Employee> topEmployees = new ArrayList<>();topEmployees.add(resultOne);topEmployees.add(employee);System.out.println(topEmployees);}
}

?方案B

        //B方案Map<String, List<Employee>> groupedByDepartment = employeeList.stream()//分組.collect(Collectors.groupingBy(Employee::getDepartment));List<Employee> topEmployees = new ArrayList<>();for (List<Employee> departmentEmployees : groupedByDepartment.values()) {Employee topEmployee = departmentEmployees.stream().max(Comparator.comparingDouble(Employee::getMonthlySalary))//注意,如果一個部門沒有員工,那么這個方法將返回null//該方法在給定的流中找不到元素時返回一個默認值。.orElse(null);if (topEmployee != null) {topEmployees.add(topEmployee);}}System.out.println(topEmployees);

我們要注意的是stream流是方便操作集合/數組的手段,集合/數組才是開發中的目的。

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

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

相關文章

【開源】基于Vue和SpringBoot的智能教學資源庫系統

項目編號&#xff1a; S 050 &#xff0c;文末獲取源碼。 \color{red}{項目編號&#xff1a;S050&#xff0c;文末獲取源碼。} 項目編號&#xff1a;S050&#xff0c;文末獲取源碼。 目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、功能模塊2.1 數據中心模塊2.2 課程檔案模塊2.3 課…

原理Redis-SkipList

SkipList ZipList和QuickList的共同特點是節省內存。在遍歷元素時&#xff0c;只能從頭到尾或從尾到頭&#xff0c;所以在查找頭尾元素性能還是不錯的&#xff0c;但是中間元素查詢的性能就會差。 **SkipList&#xff08;跳表&#xff09;**首先是鏈表&#xff0c;但與傳統鏈表…

【算法】鏈表-20231123

這里寫目錄標題 一、19. 刪除鏈表的倒數第 N 個結點二、21. 合并兩個有序鏈表三、24. 兩兩交換鏈表中的節點 一、19. 刪除鏈表的倒數第 N 個結點 提示 中等 給你一個鏈表&#xff0c;刪除鏈表的倒數第 n 個結點&#xff0c;并且返回鏈表的頭結點。 輸入&#xff1a;head [1,…

第十二章 : Spring Boot 日志框架詳解

第十二章 : Spring Boot 日志框架詳解 前言 本章知識重點:介紹了日志誕生背景,4種日志框架:Logback、Log4j、Log4j2和Slf4j的優劣勢分析,以及重點介紹了log4j2的應用示例以及配置,以及日志框架應用中遇到常見的問題以及如何處理。 背景 Java日志框架的發展歷程可以追…

在PyCharm中正確設置Python項目

大家好&#xff0c;在Mac和Linux都支持Python&#xff0c;但許多開發者發現正確設置Python項目很困難。本文匯總了多平臺中運行Python的方法&#xff0c;提高編程的效率&#xff0c;如下所示&#xff1a; 使用命令行運行Python。 在PyCharm&#xff08;免費社區版&#xff09;…

【技巧】PDF文件如何編輯?

日常辦公中我們經常會用到PDF文件&#xff0c;PDF具備很好的兼容性、穩定性及安全性&#xff0c;但卻不容易編輯&#xff0c;那PDF要如何編輯呢&#xff1f; 如果打開PDF文件就只是只讀的性質&#xff0c;說明文件是在線打開&#xff0c;或者通過PDF閱讀器打開的&#xff0c;這…

Navmesh 尋路

用cocos2dx引擎簡單實現了一下navmesh的多邊形劃分&#xff0c;然后基于劃分多邊形的a*尋路。以及路徑拐點優化算法 用cocos主要是方便使用一些渲染接口和定時器。重點是實現的原理。 首先畫了一個帶有孔洞的多邊形 //多邊形的頂點數據Vec2(100, 100),Vec2(300, 200),Vec2(50…

高防服務器的工作原理

在當今互聯網時代&#xff0c;網絡安全問題日益突出&#xff0c;各種網絡攻擊層出不窮。為了保護企業的網絡安全&#xff0c;高防服務器應運而生。那么&#xff0c;你是否了解高防服務器的工作原理呢&#xff1f;下面就讓我們一起來探索一下。 高防服務器是一種能夠有效抵御各種…

語音識別入門——常用軟件及python運用

工具以及使用到的庫 ffmpegsoxaudacitypydubscipylibrosapyAudioAnalysisplotly 本文分為兩個部分&#xff1a; P1&#xff1a;如何使用ffmpeg和sox處理音頻文件 P2&#xff1a;如何編程處理音頻文件并執行基本處理 P1 處理語音數據——命令行方式 格式轉換 ffmpeg -i video…

shell 腳本循環語句

目錄 循環 echo 命令 for 循環次數 for 第二種格式 命令舉例 while 腳本舉例 雙重循環及跳出循環 腳本舉例 更改文件和目錄的后綴名的腳本 畫三角形的腳本 乘法口訣表的腳本 面試例題 補充命令 let 命令 循環 —— 一定要有跳出循環的條件 已知循環的次數 未知…

英語六級范文模板

目錄 現象解釋 觀點選擇 問題解決 六級只考議論文&#xff0c;我們將從現象解釋&#xff0c;觀點選擇&#xff0c;問題解決三個角度給出范文&#xff1a; 多次使用的句子&#xff0c;就可以作為模板記下來~~ 現象解釋 In the contemporary world, the ability to meet cha…

SQLite3

數據庫簡介 常用的數據庫 大型數據庫&#xff1a;Oracle 中型數據庫&#xff1a;Server 是微軟開發的數據庫產品&#xff0c;主要支持 windows 平臺。 小型數據庫&#xff1a;mySQL 是一個小型關系型數據庫管理系統&#xff0c;開放源碼 。(嵌入式不需要存儲太多數據。) SQL…

點云從入門到精通技術詳解100篇-基于點云數據的機器人裝焊 過程在線測量(下)

目錄 裝焊過程在線測量技術研究 4.1 測量參數介紹 4.1.1 筋板定位測量參數

Rust個人學習之結構體

第一反應&#xff0c;Rust結構體跟python的很像&#xff0c;不知道感覺對不對&#xff1b; 書中提到第一反應&#xff0c;Rust結構體跟python的很像&#xff0c;不知道感覺對不對&#xff1b; 書中提到&#xff1a;結構體是一種自定義數據類型&#xff0c;它允許命名多個相關的…

Seaborn畫圖顏色和給定的RGB hex code不一致

使用以下代碼畫圖&#xff1a; import seaborn as sns import matplotlib.pyplot as plt plt.figure(dpi150) x [A,B,C,D] y [164, 86, 126, 53] sns.barplot(xx, yy, color#3a923a) 得到的顏色如下圖所示&#xff1a; 這是因為seaborn默認降低了顏色的飽和度&#xff0c;即…

UDP中connect的作用

udpclientNoConnect.c里邊的內容如下&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include <errno.h> #include <syslog.h…

23屆萬興校招golang一面面經

問題有結合我的簡歷來問,面試官還是很友好的 1、你是如何學習go的(擴展講) go語言的基本概念和語法&#xff0c;上手golang開源項目跟架構(gin,gorm)&#xff0c;資料找官網。 2、項目深挖 為什么選擇gin? Gin路由使用了前綴樹算法&#xff0c;beego路由使用的正則算法和較為重…

基于 Flink CDC 打造企業級實時數據集成方案

本文整理自Flink數據通道的Flink負責人、Flink CDC開源社區的負責人、Apache Flink社區的PMC成員徐榜江在云棲大會開源大數據專場的分享。本篇內容主要分為四部分&#xff1a; CDC 數據實時集成的挑戰Flink CDC 核心技術解讀基于 Flink CDC 的企業級實時數據集成方案實時數據集…

獨立版求職招聘平臺小程序開發

小程序招聘系統開發 我們開發了一款高效、便捷的互聯網招聘平臺。在這里&#xff0c;可以輕松實現企業入駐、職位發布、在線求職、精準匹配職位和人才&#xff0c;以及參與招聘會等功能。目標是為求職者和企業搭建一個連接彼此的橋梁&#xff0c;幫助您更快地找到滿意的工作&…

SpringMVC(五)SpringMVC的視圖

SpringMVC中的視圖是View接口&#xff0c;視圖的作用渲染數據&#xff0c;將模型Model中的數據展示給用戶 SpringMVC視圖的種類很多&#xff0c;默認有轉發視圖(InternalResourceView)和重定向視圖(RedirectView) 當工程引入jstl的依賴&#xff0c;轉發視圖會自動轉換為JstlV…