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("---------------------------------------
");
System.out.println("集合遍歷 Lambda");
Iloveyou.forEach(str -> System.out.println(str));
//集合遍歷 MethodReference
System.out.println("---------------------------------------
");
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("---------------------------------------
");
System.out.println(" 靜態方法引用 按年齡排序");
students.sort(StaticStudentComparator::staticCompareStudentByAge);
students.forEach(System.out::println);
System.out.println("---------------------------------------
");
System.out.println(" 靜態方法引用 按姓名排序");
students.sort(StaticStudentComparator::staticCompareStudentByName);
students.forEach(System.out::println);
2、 物件例項方法引用
// 2、 物件例項方法引用
// 物件例項方法引用 引用名(物件名)::例項方法名
// 物件例項方法引用 功能實現等價於 呼叫 物件例項 所擁有的 例項方法
StudentComparator studentComparator = new StudentComparator();
System.out.println("---------------------------------------
");
System.out.println(" 靜態方法引用 按年齡排序");
students.sort(studentComparator::compareStudentByAge);
students.forEach(System.out::println);
System.out.println("---------------------------------------
");
System.out.println(" 物件例項方法引用 按姓名排序");
students.sort(studentComparator::compareStudentByName);
students.forEach(System.out::println);
3、 類例項方法引用
// 3、 類例項方法引用
// 類例項方法引用 類名::例項方法名
System.out.println("---------------------------------------
");
System.out.println(" 類例項方法引用 按年齡排序");
students.sort(Student::classCompareStudentByAge);
students.forEach(System.out::println);
System.out.println("---------------------------------------
");
System.out.println(" 類例項方法引用 按姓名排序");
students.sort(Student::classCompareStudentByName);
students.forEach(System.out::println);
System.out.println("---------------------------------------
");
System.out.println(" 類例項方法引用 容易理解的 字串排序");
snames.sort(String::compareToIgnoreCase);
snames.forEach(System.out::println);
4、 構造方法引用
// 4、 構造方法引用
// 構造方法引用 類名::new
// 注意: 實體類Student 事先 有定義好的 全參構造方法 與無參構造方法
// 若沒有構造方法 需要自行新增 否則報錯
// Student::new 可以根據引數不同 對構造方法進行自動識別 過載
// 利用無參構造方法構造studentNoArgs物件
System.out.println("---------------------------------------
");
System.out.println("利用無參構造方法構造studentNoArgs物件");
Student studentNoArgs = this.studentSupplier(Student::new);
System.out.println(studentNoArgs);
// 利用自定義全參構造方法構造student物件
System.out.println("---------------------------------------
");
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.851 INFO 16876 --- [ main] c.j.d.j.MethodReference.MethodReference : Starting MethodReference on DESKTOP-87RMBG4 with PID 16876 (started by 46250 in E:IdeaProjectsdesign)
2019-02-02 17:04:20.852 INFO 16876 --- [ main] c.j.d.j.MethodReference.MethodReference : No active profile set, falling back to default profiles: default
2019-02-02 17:04:21.422 INFO 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)