在日常的開發工作中經常碰到要處理 List 中資料的問題,例如從一個物件集合中獲得物件中的一個屬性的集合。之前我們想到的是遍歷每個元素,然後取出來放到另外一個集合中,比較繁瑣;在 Java8 之後,對集合可以進行 Stream 操作,使上面的處理更簡潔。
Stream 串流處理中有map() 方法,先看下其定義,該方法在java.util.stream.Stream類別中
可以看到map() 方法接收一個函數式介面參數,入參有一個T ,回傳一個Stream 流,這個流是R 泛型。主要有以下幾點注意,
入參是一個流中的元素;
出參是一個流,且流中是新元素;
用圖表示就是下面的樣子,原始流中有四個圓形圖案,呼叫map() 函數後變成了四個五角星圖案,這裡的圓形圖案和五角星圖案是一一對應的,也就是原始流中有多少個元素,呼叫map() 方法後依舊有多少個元素,唯一改變的是流中的元素類型。
我們先建立一個實體類別Student.java
@Data public class Student implements Serializable { /** * 姓名 */ private String name; /** * 班级 */ private String schoolClass; /** *语文成绩 */ private Integer chineseScore; /** * 数学成绩 */ private Integer mathScore; }
再建立一個初始化資料的類別:
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中,可以实现去重功能 Set<String> studentNames = DataFactory.initData().stream() .map(student -> student.getName()) .collect(Collectors.toSet());
結果不再列印,有興趣的可以自己試試。
將名字為「湯霖」的語文成績置為90
現在有這樣一個需求,要把姓名為湯霖學生的語文成績置為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 StreamAPI中的map()方法怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!