深入理解 lambda表达式 与 MethodReference(四)

44次阅读

共计 9917 个字符,预计需要花费 25 分钟才能阅读完成。

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

正文完
 0