前言
在日常的開發(fā)工作中經(jīng)常碰到要處理 List 中數(shù)據(jù)的問題,比如從一個(gè)對(duì)象集合中獲得對(duì)象中的一個(gè)屬性的集合。之前我們想到的是遍歷每個(gè)元素,然后取出來放到另外一個(gè)集合中,比較繁瑣;在 Java8 之后,對(duì)集合可以進(jìn)行 Stream 操作,使上面的處理更簡(jiǎn)潔。
概述
Stream 流式處理中有 map() 方法,先看下其定義,該方法在java.util.stream.Stream類中
可以看到 map() 方法接收一個(gè)函數(shù)式接口參數(shù),入?yún)⒂幸粋€(gè) T ,返回一個(gè) Stream 流,這個(gè)流是 R 泛型。主要有以下幾點(diǎn)注意,
- 入?yún)⑹且粋€(gè)流中的元素;
- 出參是一個(gè)流,且流中是新元素;
用圖表示就是下面的樣子,原始流中有四個(gè)圓形圖案,調(diào)用 map() 函數(shù)后變成了四個(gè)五角星圖案,這里的圓形圖案和五角星圖案是一一對(duì)應(yīng)的,也就是原始流中有多少個(gè)元素,調(diào)用 map() 方法后依舊有多少個(gè)元素,唯一改變的是流中的元素類型。
示例
我們先創(chuàng)建一個(gè)實(shí)體類 Student.java
@Data
public class Student implements Serializable {
/**
* 姓名
*/
private String name;
/**
* 班級(jí)
*/
private String schoolClass;
/**
*語文成績(jī)
*/
private Integer chineseScore;
/**
* 數(shù)學(xué)成績(jī)
*/
private Integer mathScore;
}
再創(chuàng)建一個(gè)初始化數(shù)據(jù)的類:
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("二年級(jí)");
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("大運(yùn)");
s5.setSchoolClass("小三班");
s5.setChineseScore(96);
s5.setMathScore(100);
list.add(s5);
return list;
}
}
找出所有的學(xué)生姓名
public static void main(String[] args) {
DataFactory.initData().stream()
.map(student - > student.getName())
.forEach(System.out::println);
}
這里使用了 map() 方法,入?yún)⑹?Student,出參是以 String 為泛型的流,最后使用 forEach 進(jìn)行了打印,看下結(jié)果
可以看到剛好把所有的學(xué)生姓名均打印出來了。如果想把這些學(xué)生姓名放到一個(gè)List中怎么辦?
將學(xué)生姓名放到list中
public static void main(String[] args) {
//將所有的學(xué)生姓名放到list中
List< String > studentNames = DataFactory.initData().stream()
.map(student - > student.getName())
.collect(Collectors.toList());
for (String studentName : studentNames) {
System.out.println(studentName);
}
}
同樣的找出所有的班級(jí),找出所有學(xué)生的成績(jī)都可類比上面的,可以看到打印出的學(xué)生姓名或班級(jí)是有重復(fù)數(shù)據(jù),這個(gè)要怎么解決。我們知道在最后是把數(shù)據(jù)放到 List 中,為了解決重復(fù)的問題可以把數(shù)據(jù)放到 Set 中,利用 Set 的去重功能:
//將學(xué)生姓名放到Set中,可以實(shí)現(xiàn)去重功能
Set< String > studentNames = DataFactory.initData().stream()
.map(student - > student.getName())
.collect(Collectors.toSet());
結(jié)果不再打印,有興趣的可以自己試試。
將姓名為“湯霖”的語文成績(jī)置為90
現(xiàn)在有這樣一個(gè)需求,要把姓名為湯霖學(xué)生的語文成績(jī)置為90
,看下利用 map() 函數(shù)怎么做?
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("-----改之前的數(shù)據(jù)-----");
for (Student studentName : students) {
System.out.println(studentName);
}
}
輸出結(jié)果:
從上面的結(jié)果中可以看出,湯霖的語文成績(jī)的確被改為了90
,這點(diǎn)是沒錯(cuò)的。再看原數(shù)據(jù)也被改為了90
,上面提到過 map() 方法生成的是一個(gè)新流,原始流中的數(shù)據(jù)也被修改了,因?yàn)橄旅孢@行代碼是在原始流中元素的基礎(chǔ)上修改的引用類型中的數(shù)據(jù),導(dǎo)致的原始流中的數(shù)據(jù)也會(huì)改。
總結(jié)
Java8 的 Stream 流 map() 方法是將流中的元素轉(zhuǎn)換為另外一個(gè)流中的元素,轉(zhuǎn)換前后兩個(gè)流的元素個(gè)數(shù)不發(fā)生改變。
-
接口
+關(guān)注
關(guān)注
33文章
8885瀏覽量
152958 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7233瀏覽量
90730 -
JAVA
+關(guān)注
關(guān)注
20文章
2983瀏覽量
106487 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4365瀏覽量
63838 -
Stream
+關(guān)注
關(guān)注
0文章
21瀏覽量
8077
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
Stream API原理介紹
JAVA學(xué)習(xí)直通車(教程+書籍+100個(gè)實(shí)例+問題與解答)
Java Map的幾種循環(huán)方式學(xué)習(xí)總結(jié)
Java并行流存在的問題及解決辦法詳解
如何利用Stream API來優(yōu)化Java代碼
JAVA8提供了Optional類來優(yōu)化這種寫法
JDK8 Stream數(shù)據(jù)流效率分析
java的stream編程調(diào)試技巧
Java 8 Stream流底層原理
怎么使用Java8的Stream API比較兩個(gè)List的差異呢?
List 轉(zhuǎn) Map的方法
Java8的新特性
Java的Stream的常用知識(shí)

為什么需要Streams?它們能取代Java中的for循環(huán)嗎?

評(píng)論