詳解Java8?StreamAPI中的map()方法
Stream API 是Java8中新加入的功能,現(xiàn)在都 Java20 了,不會還有人沒用過吧?
今天給大家演示一下 Stream API 中的 map() 方法。
前言
在日常的開發(fā)工作中經常碰到要處理 List 中數據的問題,比如從一個對象集合中獲得對象中的一個屬性的集合。之前我們想到的是遍歷每個元素,然后取出來放到另外一個集合中,比較繁瑣;在 Java8 之后,對集合可以進行 Stream 操作,使上面的處理更簡潔。
概述
Stream 流式處理中有 map() 方法,先看下其定義,該方法在java.util.stream.Stream類中

可以看到 map() 方法接收一個函數式接口參數,入參有一個 T ,返回一個 Stream 流,這個流是 R 泛型。主要有以下幾點注意,
- 入參是一個流中的元素;
- 出參是一個流,且流中是新元素;
用圖表示就是下面的樣子,原始流中有四個圓形圖案,調用 map() 函數后變成了四個五角星圖案,這里的圓形圖案和五角星圖案是一一對應的,也就是原始流中有多少個元素,調用 map() 方法后依舊有多少個元素,唯一改變的是流中的元素類型。

示例
我們先創(chuàng)建一個實體類 Student.java
@Data
public?class?Student?implements?Serializable?{
????/**
?????*?姓名
?????*/
????private?String?name;
????/**
?????*?班級
?????*/
????private?String?schoolClass;
????/**
?????*語文成績
?????*/
????private?Integer?chineseScore;
????/**
?????*?數學成績
?????*/
????private?Integer?mathScore;
}
再創(chuàng)建一個初始化數據的類:
public?class?DataFactory?{
????public?static?List<Student>?initData(){
????????List<Student>?list=?new?ArrayList<>();
????????Student?s1=new?Student();
????????s1.setName("湯霖");
????????s1.setSchoolClass("小一班");
????????s1.setChineseScore(87);
????????s1.setMathScore(95);
????????list.add(s1);
?
????????Student?s2=new?Student();
????????s2.setName("李牧唐");
????????s2.setSchoolClass("小二班");
????????s2.setChineseScore(98);
????????s2.setMathScore(97);
????????list.add(s2);
?
????????Student?s3=new?Student();
????????s3.setName("顧北辰");
????????s3.setSchoolClass("二年級");
????????s3.setChineseScore(89);
????????s3.setMathScore(94);
????????list.add(s3);
?
????????Student?s4=new?Student();
????????s4.setName("言言");
????????s4.setSchoolClass("小二班");
????????s4.setChineseScore(100);
????????s4.setMathScore(90);
????????list.add(s4);
?
????????Student?s5=new?Student();
????????s5.setName("大運");
????????s5.setSchoolClass("小三班");
????????s5.setChineseScore(96);
????????s5.setMathScore(100);
????????list.add(s5);
????????return?list;
????}
}
找出所有的學生姓名
public?static?void?main(String[]?args)?{
??? DataFactory.initData().stream()
????????.map(student?->?student.getName())
????????.forEach(System.out::println);
}
這里使用了 map() 方法,入參是 Student,出參是以 String 為泛型的流,最后使用 forEach 進行了打印,看下結果

可以看到剛好把所有的學生姓名均打印出來了。如果想把這些學生姓名放到一個List中怎么辦?
將學生姓名放到list中
public?static?void?main(String[]?args)?{
????//將所有的學生姓名放到list中
????List<String>?studentNames = DataFactory.initData().stream()
????????.map(student?->?student.getName())
????????.collect(Collectors.toList());
????for?(String?studentName : studentNames)?{
????????System.out.println(studentName);
????}
}
同樣的找出所有的班級,找出所有學生的成績都可類比上面的,可以看到打印出的學生姓名或班級是有重復數據,這個要怎么解決。我們知道在最后是把數據放到 List 中,為了解決重復的問題可以把數據放到 Set 中,利用 Set 的去重功能:
//將學生姓名放到Set中,可以實現(xiàn)去重功能 Set<String>?studentNames = DataFactory.initData().stream() ????.map(student?->?student.getName()) ????.collect(Collectors.toSet());
結果不再打印,有興趣的可以自己試試。
將姓名為“湯霖”的語文成績置為90
現(xiàn)在有這樣一個需求,要把姓名為湯霖學生的語文成績置為90,看下利用 map() 函數怎么做?
public?static?void?main(String[]?args)?{
????List<Student>?students?=?DataFactory.initData();
????List<Student>?studentNames?=?students.stream().map(student?->?{
????????if?("湯霖".equals(student.getName()))?{
????????????student.setChineseScore(90);
????????}
????????return?student;
????}).collect(Collectors.toList());
????for?(Student?studentName?:?studentNames)?{
????????System.out.println(studentName);
????}
????//打印老的list
????System.out.println("-----改之前的數據-----");
????for?(Student?studentName?:?students)?{
????????System.out.println(studentName);
????}
}
輸出結果:

從上面的結果中可以看出,湯霖的語文成績的確被改為了90,這點是沒錯的。再看原數據也被改為了90,上面提到過 map() 方法生成的是一個新流,原始流中的數據也被修改了,因為下面這行代碼是在原始流中元素的基礎上修改的引用類型中的數據,導致的原始流中的數據也會改。
總結
Java8 的 Stream 流 map() 方法是將流中的元素轉換為另外一個流中的元素,轉換前后兩個流的元素個數不發(fā)生改變。
到此這篇關于詳解Java8 StreamAPI中的map()方法的文章就介紹到這了,更多相關Java8 StreamAPI map內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Springboot項目編譯后未能加載靜態(tài)資源文件的問題
這篇文章主要介紹了Springboot項目編譯后未能加載靜態(tài)資源文件的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
Mybatis?Interceptor線程安全引發(fā)的bug問題
這篇文章主要介紹了Mybatis?Interceptor線程安全引發(fā)的bug問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02
創(chuàng)建動態(tài)代理對象bean,并動態(tài)注入到spring容器中的操作
這篇文章主要介紹了創(chuàng)建動態(tài)代理對象bean,并動態(tài)注入到spring容器中的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
Java源碼深度分析String與StringBuffer及StringBuilder詳解
當對字符串進行修改的時候,需要使用?StringBuffer?和?StringBuilder類,和String類不同的是,StringBuffer和?StringBuilder類的對象能夠被多次的修改,并且不產生新的未使用對象,本篇我們來分析分析它們的源碼2022-05-05
Java中Easypoi實現(xiàn)excel多sheet表導入導出功能
這篇文章主要介紹了Java中Easypoi實現(xiàn)excel多sheet表導入導出功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01
SpringBoot中讀取jar包中的resources目錄下的文件的三種方式
這篇文章給大家總結了SpringBoot讀取 jar 包中的 resources 目錄下的文件的三種方式,文中有詳細的代碼示例供大家參考,,需要的朋友可以參考下2023-06-06

