深刻理解 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 {

1、測試數據準備

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");

}

2、方法引用 引入

@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);

3、什麼是方法引用

//  MethodReference
//  方法引用是Lambda表達式的特殊替換
//  方法引用本質是一個 函數指針 Function Pointer
//  這個指針指向被引用方法
//  eg: 方法引用System.out::println 指向System.out.println()這個函數

4、方法引用的分類

一、 靜態方法引用java

//   一、 靜態方法引用

//   靜態方法引用 類名::靜態方法名
//   靜態方法引用 功能實現等價於 調用 類的靜態方法

//   靜態方法引用 與 調用  無任何關係
//          類名.靜態方法名   -->方法調用  顯示傳參
//          類名::靜態方法名  -->方法引用  隱式傳參  編譯器自動推斷  方法引用的表達式 函數指針 指向 被引用函數
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);

二、 對象實例方法引用spring

//   二、 對象實例方法引用

//   對象實例方法引用 引用名(對象名)::實例方法名
//   對象實例方法引用 功能實現等價於 調用 對象實例 所擁有的 實例方法
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);

三、 類實例方法引用函數

//   三、 類實例方法引用
//   類實例方法引用 類名::實例方法名

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);

四、 構造方法引用測試

//  四、  構造方法引用
//  構造方法引用 類名::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);


    }
}

5、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);
    }


}

6、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);
    }

}

7、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());
    }
}

9、 測試結果

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: 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:\IdeaProjects\design)
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)
相關文章
相關標籤/搜索