目錄
Stream
map
filter
flatmap
collect
CompletableFuture
流處理stream結合函式式編程規范,極大提升編程效率,減少代碼量,而異步編程completableFuture的使用,則能夠更加清晰地表述出業務邏輯,方法的異步呼叫關系路徑很好滴描述了業務脈絡;
Stream
這里先構造2個物件,student和teacher,teacher擁有多個student物件,經常有類似使用teacher物件后對student操作的場景,使用流處理比for、foreach、Iterator更優雅;
package org.example;
import org.example.model.Student;
import org.example.model.Teacher;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) {
System.out.println("begin.");
Student a = new Student(1, "001", "zhangsan", "1");
Student b = new Student(2, "001", "lisi", "2");
Student c = new Student(3, "001", "wangwu", "3");
Student d = new Student(4, "001", "mazi", "4");
Student e = new Student(5, "001", "zhaowu", "5");
Student f = new Student(6, "001", "xuliu", "6");
Student g = new Student(7, "001", "dongqi", "7");
Student h = new Student(8, "001", "chenba", "8");
List<Student> studentList = new ArrayList<Student>();
studentList.add(a);
studentList.add(b);
studentList.add(c);
studentList.add(d);
studentList.add(e);
studentList.add(f);
studentList.add(g);
studentList.add(h);
Teacher t1 = new Teacher(1, "12", "boy", "laoshi", studentList);
}
}
map
map通過映射直接拿到屬性值,回傳的是屬性而并非原有物件,有多重寫法:
List<Integer> list = t1.getStudentList()
.stream()
.map(Student::getId)
.collect(Collectors.toList());
List<Integer> list1 = t1.getStudentList()
.stream()
.map(student -> student.getId())
.collect(Collectors.toList());
System.out.println(list);
System.out.println(list1);
也可以在取值時候做轉換運算:
// map做運算
List<Integer> list2 = t1.getStudentList()
.stream()
.map(student -> {
return student.getId() + 1;
}).collect(Collectors.toList());
System.out.println("list2:" + list2);
filter
filter過濾,回傳的是原有物件:
// filter過濾
List<Student> list3 = t1.getStudentList()
.stream()
.filter(student -> {
return student.getId() > 3;
}).filter(student -> {
return student.getName().contains("s");
}).collect(Collectors.toList());
System.out.println("list3:" + list3);
List<Student> list4 = t1.getStudentList()
.stream()
.filter(student -> student.getId() > 2)
.collect(Collectors.toList());
flatmap
flatmap拍扁,跟flink中的流式處理定義相似,輸出一對多
// flatmap拍扁,輸出值
BinaryOperator<Student> getBiggestID = (x1, x2) -> {
int id1 = x1.getId();
int id2 = x2.getId();
return x1.getId() > x2.getId() ? x1 : x2;
};
Integer maxID = Optional.ofNullable(t1.getStudentList())
.flatMap(students -> students.stream().reduce(getBiggestID))
.map(Student::getId)
.orElse(0);
System.out.println(maxID);
collect
可以流處理同樣可以聚合,groubpingby函式為例:
// groupby轉化
Map<String,List<Student>> list6 = t1.getStudentList().stream()
.filter(student -> !student.getName().isEmpty())
.collect(Collectors.groupingBy(x->x.getName().contains("s")?"ss":"nn"));
System.out.println(list6);
CompletableFuture
當需要對Teacher和Student物件進行查詢邏輯處理時候,就可以用異步編程相關方法;在方法的定義加上CompletableFuture<>關鍵詞,把回傳值放在泛型中,比如CompletableFuture<List<Student>>getStudents()方法,如果不使用異步編程直接回傳List,使用異步編程回傳CompletableFuture物件,在使用時候;
package org.example.service;
import org.example.model.Student;
import org.example.model.Teacher;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static java.util.concurrent.CompletableFuture.completedFuture;
public class TeacherServiceImpl {
Student a = new Student(1, "sat", "zhangsan", "1");
Student b = new Student(2, "hhh", "lisi", "2");
Student c = new Student(3, "kg", "wangwu", "3");
Student d = new Student(4, "ss", "mazi", "4");
Student e = new Student(5, "tt", "zhaowu", "5");
Student f = new Student(6, "dfa", "xuliu", "6");
Student g = new Student(7, "safg", "dongqi", "7");
Student h = new Student(8, "tsa", "chenba", "8");
List<Student> students = new ArrayList<Student>();
// 假設需要進行資料庫查詢操作
public CompletableFuture<List<Student>> getStudents(){
Student a = new Student(1, "sat", "zhangsan", "1");
Student b = new Student(2, "hhh", "lisi", "2");
Student c = new Student(3, "kg", "wangwu", "3");
Student d = new Student(4, "ss", "mazi", "4");
Student e = new Student(5, "tt", "zhaowu", "5");
Student f = new Student(6, "dfa", "xuliu", "6");
Student g = new Student(7, "safg", "dongqi", "7");
Student h = new Student(8, "tsa", "chenba", "8");
List<Student> studentList = new ArrayList<Student>();
studentList.add(a);
studentList.add(b);
studentList.add(c);
studentList.add(d);
studentList.add(e);
studentList.add(f);
studentList.add(g);
studentList.add(h);
studentList.add(h);
return completedFuture(studentList);
}
// 對資料庫回傳值再加工
public CompletableFuture<List<Teacher>> getTeachers(List<Student> students){
List<Teacher> teachers = new ArrayList<Teacher>();
Teacher t2 = new Teacher(1, "12", "boy", "lixx", students);
Teacher t3 = new Teacher(3, "21", "girl", "wangxx", students);
teachers.add(t2);
teachers.add(t3);
return completedFuture(teachers);
}
}
對Student是資料庫操作,對teacher是資料庫回傳的在處理,那么作為impl,就可以組合進行業務邏輯鏈路:
// 異步編程鏈路
public static CompletableFuture<String> test(){
return teacherService.getStudents()
.thenApplyAsync(students -> students.stream()
.filter(i->i.getName().contains("s"))
.collect(Collectors.toList()))
.thenApply(students -> teacherService.getTeachers(students).toString())
.toCompletableFuture();
}
關于thencompose和thenapply方法需要搞明白;
supplyAsync(Func):引數為計算任務(函式),該方法會異步執行傳入的Func函式,并且使用get或join方法獲取計算結果;
runAsync(Func):該方法也可以創建CompletableFuture實體,只是適合創建無回傳值的Func;
thenApply():then開頭的函式都是函式執行后的操作,thenApply前后兩個任務在同一個執行緒中執行,thenApplyAsyn前后兩個任務不是同一個執行緒,而是兩個不同執行緒,相同點是都要等前一個方法結束后才會執行后面跟著的方法,thenApply函式傳入的函式需要有入參和出參;
thenCombine():與thenApply相比,更強調前后連接任務的關系是并行的,也就是Func可以和后面連接的函式并行處理,最后兩個任務均完成將結果同時傳遞給下游任務,
thenCompose():當前后兩個任務存在關聯關系,當第一個任務完成時才會執行第二個操作就可以使用thenCompose方法,兩個異步任務全部完成時才會執行某些操作用thenCombine,
whenComplete():任務完成后的回呼;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/298433.html
標籤:其他
上一篇:【趙強老師】史上最詳細的PostgreSQL體系架構介紹
下一篇:MySQL45講之更新快取
