深入理解 lambda表示式 與 MethodReference(四)
package com.java.design.java8.MethodReference; import com.java.design.java8.entity.Student; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.List; import java.util.function.Supplier; /** * @author 陳楊 */ @RunWith(SpringRunner.class) @SpringBootTest public class MethodReference {
一、測試資料準備
private List<Student> students; private List<String> snames; private Student studentSupplier(Supplier<Student> studentSupplier) { return studentSupplier.get(); } //private StudentConstructor studentConstructor = //(id, name, sex, age, addr, salary) -> //new Student(id, name, sex, age, addr, salary); private StudentConstructor studentConstructor = Student::new; private Student studentAllArgs(Integer id, String name, String sex, Integer age, String addr, Double salary) { return studentConstructor.studentAllArgs(id, name, sex, age, addr, salary); } @Before public void init() { Student kirito = new Student(1, "Kirito", "Male", 18, "Sword Art Online", 999999999.0); Student Asuna = new Student(2, "Asuna", "Female", 17, "Sword Art Online", 999999999.0); Student Sinon = new Student(3, "Sinon", "Female", 16, "Gun Gale Online", 999999999.0); Student Yuuki = new Student(4, "Yuuki", "Female", 15, "Alfheim Online", 999999999.0); Student Alice = new Student(5, "Alice", "Female", 14, "Alicization", 999999999.0); students = Arrays.asList(kirito, Asuna, Sinon, Yuuki, Alice); snames = Arrays.asList("kirito", "Asuna", "Sinon", "Yuuki", "Alice"); }
二、方法引用 引入
@Test public void testMethodReference() { //MethodReference 方法引用 List<String> Iloveyou = Arrays.asList("Kirito", "Love", "Asuna"); //集合遍歷 Lambda System.out.println("---------------------------------------\n"); System.out.println("集合遍歷 Lambda"); Iloveyou.forEach(str -> System.out.println(str)); //集合遍歷 MethodReference System.out.println("---------------------------------------\n"); System.out.println("集合遍歷 MethodReference"); Iloveyou.forEach(System.out::println);
三、什麼是方法引用
//MethodReference //方法引用是Lambda表示式的特殊替換 //方法引用本質是一個 函式指標 Function Pointer //這個指標指向被引用方法 //eg: 方法引用System.out::println 指向System.out.println()這個函式
四、方法引用的分類
1、 靜態方法引用
//1、 靜態方法引用 //靜態方法引用 類名::靜態方法名 //靜態方法引用 功能實現等價於 呼叫 類的靜態方法 //靜態方法引用 與 呼叫無任何關係 //類名.靜態方法名-->方法呼叫顯示傳參 //類名::靜態方法名-->方法引用隱式傳參編譯器自動推斷方法引用的表示式 函式指標 指向 被引用函式 System.out.println("---------------------------------------\n"); System.out.println(" 靜態方法引用 按年齡排序"); students.sort(StaticStudentComparator::staticCompareStudentByAge); students.forEach(System.out::println); System.out.println("---------------------------------------\n"); System.out.println(" 靜態方法引用 按姓名排序"); students.sort(StaticStudentComparator::staticCompareStudentByName); students.forEach(System.out::println);
2、 物件例項方法引用
//2、 物件例項方法引用 //物件例項方法引用 引用名(物件名)::例項方法名 //物件例項方法引用 功能實現等價於 呼叫 物件例項 所擁有的 例項方法 StudentComparator studentComparator = new StudentComparator(); System.out.println("---------------------------------------\n"); System.out.println(" 靜態方法引用 按年齡排序"); students.sort(studentComparator::compareStudentByAge); students.forEach(System.out::println); System.out.println("---------------------------------------\n"); System.out.println(" 物件例項方法引用 按姓名排序"); students.sort(studentComparator::compareStudentByName); students.forEach(System.out::println);
3、 類例項方法引用
//3、 類例項方法引用 //類例項方法引用 類名::例項方法名 System.out.println("---------------------------------------\n"); System.out.println(" 類例項方法引用 按年齡排序"); students.sort(Student::classCompareStudentByAge); students.forEach(System.out::println); System.out.println("---------------------------------------\n"); System.out.println(" 類例項方法引用 按姓名排序"); students.sort(Student::classCompareStudentByName); students.forEach(System.out::println); System.out.println("---------------------------------------\n"); System.out.println(" 類例項方法引用 容易理解的 字串排序"); snames.sort(String::compareToIgnoreCase); snames.forEach(System.out::println);
4、構造方法引用
//4、構造方法引用 //構造方法引用 類名::new //注意: 實體類Student 事先 有定義好的 全參構造方法 與無參構造方法 //若沒有構造方法 需要自行新增 否則報錯 //Student::new 可以根據引數不同 對構造方法進行自動識別 過載 //利用無參構造方法構造studentNoArgs物件 System.out.println("---------------------------------------\n"); System.out.println("利用無參構造方法構造studentNoArgs物件"); Student studentNoArgs = this.studentSupplier(Student::new); System.out.println(studentNoArgs); //利用自定義全參構造方法構造student物件 System.out.println("---------------------------------------\n"); System.out.println("利用全參構造方法構造studentNoArgs物件"); Student Silica = this.studentAllArgs (6, "Silica", "Female", 10, "Sword Art Online", 999999999.0); System.out.println(Silica); } }
五、StaticStudentComparator類 (靜態方法例項引用)
import com.java.design.java8.entity.Student; import java.util.Comparator; public class StaticStudentComparator { static Comparator<Student> studentAgeComparator = (first, last) -> first.getAge() - last.getAge(); static Comparator<Student> studentNameComparator = (first, last) -> first.getName().compareToIgnoreCase(last.getName()); public static int staticCompareStudentByAge(Student first, Student last) { return studentAgeComparator.compare(first, last); } public static int staticCompareStudentByName(Student first, Student last) { return studentNameComparator.compare(first, last); } }
六、StudentComparator類 (物件方法例項引用)
import com.java.design.java8.entity.Student; import java.util.Comparator; public class StudentComparator { Comparator<Student> studentAgeComparator = (first, last) -> first.getAge() - last.getAge(); Comparator<Student> studentNameComparator = (first, last) -> first.getName().compareToIgnoreCase(last.getName()); public int compareStudentByAge(Student first, Student last) { return studentAgeComparator.compare(first, last); } public int compareStudentByName(Student first, Student last) { return studentNameComparator.compare(first, last); } }
七、StudentConstructor @FunctionalInterface介面 (構造方法例項引用)
import com.java.design.java8.entity.Student; @FunctionalInterface public interface StudentConstructor { Student studentAllArgs(Integer id, String name, String sex, Integer age, String addr, Double salary); }
八 、Student實體類 (類例項方法引用)
@Data @AllArgsConstructor @NoArgsConstructor public class Student { private Integer id; private String name; private String sex; private Integer age; private String addr; private Double salary; public int classCompareStudentByAge(Student student) { return this.getAge() - student.getAge(); } public int classCompareStudentByName(Student student) { return this.getName().compareToIgnoreCase(student.getName()); } }
九、 測試結果
._______ _ _ /\\ / ___'_ __ _ _(_)_ ____ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/___)| |_)| | | | | || (_| |) ) ) ) '|____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot ::(v2.1.2.RELEASE) 2019-02-02 17:04:20.851INFO 16876 --- [main] c.j.d.j.MethodReference.MethodReference: Starting MethodReference on DESKTOP-87RMBG4 with PID 16876 (started by 46250 in E:\IdeaProjects\design) 2019-02-02 17:04:20.852INFO 16876 --- [main] c.j.d.j.MethodReference.MethodReference: No active profile set, falling back to default profiles: default 2019-02-02 17:04:21.422INFO 16876 --- [main] c.j.d.j.MethodReference.MethodReference: Started MethodReference in 0.878 seconds (JVM running for 1.682) --------------------------------------- 集合遍歷 Lambda Kirito Love Asuna --------------------------------------- 集合遍歷 MethodReference Kirito Love Asuna --------------------------------------- 靜態方法引用 按年齡排序 Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8) Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8) Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8) Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8) Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8) --------------------------------------- 靜態方法引用 按姓名排序 Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8) Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8) Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8) Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8) Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8) --------------------------------------- 靜態方法引用 按年齡排序 Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8) Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8) Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8) Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8) Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8) --------------------------------------- 物件例項方法引用 按姓名排序 Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8) Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8) Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8) Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8) Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8) --------------------------------------- 類例項方法引用 按年齡排序 Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8) Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8) Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8) Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8) Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8) --------------------------------------- 類例項方法引用 按姓名排序 Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8) Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8) Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8) Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8) Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8) --------------------------------------- 類例項方法引用 容易理解的 字串排序 Alice Asuna kirito Sinon Yuuki --------------------------------------- 利用無參構造方法構造studentNoArgs物件 Student(id=null, name=null, sex=null, age=null, addr=null, salary=null) --------------------------------------- 利用全參構造方法構造studentNoArgs物件 Student(id=6, name=Silica, sex=Female, age=10, addr=Sword Art Online, salary=9.99999999E8)