Lamda(拉姆達)表示式演化過程
簡介
HI!小夥伴們,好久沒見了,4月份開始斷更,中途有點事兒,今天開始更新了,整理一篇Lamda表示式演化過程,希望喜歡的一如既往的支援!
傳統集合過濾
現在有2個需求:在一組學生集合中,1.找出年齡大於20學生;2.找出分數小於70的學生;下面讓我們看看程式碼吧!
/** * @author :jiaolian * @date :Created in 2021-07-12 15:14 * @description:學生測試 * @modified By: * 公眾號:叫練 */ public class Student { //姓名 private String name;//年齡 private int age; //分數 private double score; public Student(String name, int age, double score) { this.name = name; this.age = age; this.score = score; } public String getName() { return name; } public void setName(String name) {this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } @Override publicString toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", score=" + score + '}'; } }
List<Student> students = Arrays.asList( new Student("張三",21,58), new Student("李四",23,88), new Student("王五",19,68), new Student("叫練",25,78), new Student("jiaolian",16,98) ); //需求:1.找出年齡大於20學生;2.找出分數小於70的學生 @Test public void test1() { List<Student> stus = findStudentByAge(); System.out.println(stus); System.out.println("==========="); List<Student> stus1 = findStudentByScore(); System.out.println(stus1); } //通過年齡過濾學生 public List<Student> findStudentByAge() { List<Student> stus = new ArrayList<>(); for (int i=0; i<students.size(); i++) { if (students.get(i).getAge() > 20) { //將年齡大於20學生放入stus裡 stus.add(students.get(i)); } } return stus; } //通過分數過濾學生 public List<Student> findStudentByScore() { List<Student> stus = new ArrayList<>(); for (int i=0; i<students.size(); i++) { if (students.get(i).getScore() < 70) { //將找出分數小於70的學生放入stus裡 stus.add(students.get(i)); } } return stus; }
如上程式碼:程式碼邏輯比較簡單,findStudentByAge()方法是通過年齡過濾學生,在students學生集合中通過迴圈過濾出大於年齡20的學生放入新的集合stus中,最終返回stus物件,同理,通過分數過濾學生也是這樣,在測試方法test1中,呼叫findStudentByAge()和findStudentByScore();最終列印輸出結果如下:
程式碼的結果我們輸出了,結果輸出沒有問題,但是看上去有些臃腫,因為除了過濾條件外,for迴圈等其他的好像都是重複的,如果我們需要再增加一個通過姓名過濾學生,又得寫一個方法。針對已有程式碼,下面我們看看策略模式如何解決!
演化1:介面策略模式
我們新增一個處理學生集合的介面
/** * 學生處理介面 */ public interface StudentHandler<T> { //處理學生 boolean handlerStu(T t); }
/** * @author :jiaolian * @date :Created in 2021-07-12 15:42 * @description:處理學生年齡大於20 * @modified By: * 公眾號:叫練 */ public class HandlerAge implements StudentHandler<Student> { @Override public boolean handlerStu(Student student) { return student.getAge()>20; } }
@Test public void test2() { List<Student> res = getStudents(students,new HandlerAge()); System.out.println(res); } /** * 通過條件過濾學生 * @param stus * @param studentHandler * @return */ public List<Student> getStudents(List<Student> stus,StudentHandler<Student> studentHandler) { List<Student> res = new ArrayList<>(); for (int i=0; i<stus.size(); i++) { //介面條件 if (studentHandler.handlerStu(stus.get(i))) { res.add(stus.get(i)); } } return res; }
如上程式碼:新建StudentHandler介面處理學生,HandlerAge實現類實現了StudentHandler,用於過濾學生年齡大於20的物件,getStudents方法接收stus和studentHandler物件分別表示原始學生物件和介面實現new HandlerAge(),呼叫該方法最終列印學生年齡大於20的物件,和上面結果一致。如果現在我們需要通過分數處理,我們新增一個HandlerScore類實現StudentHandler介面就可以了,大家可以自行測試下,但是有個缺點,類變多了。下面我們看看匿名內部類如何實現過濾分數小於70的學生。
演化2:匿名內部類
@Test public void test3() { //匿名內部類實現 List<Student> res = getStudents(students, new StudentHandler<Student>() { @Override public boolean handlerStu(Student student) { return student.getScore() <70; } }); System.out.println(res); }
如上程式碼:該匿名物件實現了過濾分數小於70的學生。
演化3:lamda表示式
上面的程式碼已經足夠簡單,但自從JDK1.8開始支援了Lambda,我們針對上面的程式碼再做一次優化。
@Test public void test4() { List<Student> res = getStudents(students, student -> student.getScore() <70); System.out.println(res); }
如上程式碼:student -> student.getScore() <70注意改程式碼格式就是Lamda格式,左邊表示引數,如果有多個引數需要用括號表示,右邊是實現過程,看!寫法上非常簡單,注意:lamda需要函式介面支援:那什麼是函式介面呢,只有一個抽象方法的介面稱為函式介面。他的好處是簡化表達,程式碼更通俗易懂,同時需要jdk1.8以上版本支援哦!
總結
好啦,今天我們就講到這裡,希望大家有疑問可以提問,歡迎和我交流。我是【公眾號:叫練】,邊叫邊練;喜歡的可以加關注哦!再次感謝大家的觀看支援。