方法引用
- 把已经有的方法拿过来用,当作函数式接口中抽象方法的方法体
- 使用条件
- 引用处必须是函数式接口
- 被引用的方法必须已经存在
- 被引用方法的形参和返回值需要跟抽象方法保持一致
- 被引用方法的功能要满足当前需求
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
//这个类叫做FunctionDemo1
Arrays.sort(arr, FunctionDemo1::subtraction);
//可以是Java已经写好的,也可以是一些第三方工具类
public static int subtraction(int num1, int num2) {
return num2 - num1;
}
引用静态方法
- 格式
类名::静态方法
- 范例
Integer::parseInt
引用成员方法
- 格式
对象::成员方法- 其他类:
其他类对象::方法名- 注意:是其他类的对象:
new StringOperation()::stringJudge
- 注意:是其他类的对象:
- 本类:
this::方法名- 如果引用处是静态方法,在静态方法中是没有this的,所以想要在静态方法中引用本类的方法,只能先new一个本类的对象:
new FunctionDemo3()::stringJudge
- 如果引用处是静态方法,在静态方法中是没有this的,所以想要在静态方法中引用本类的方法,只能先new一个本类的对象:
- 父类:
super::方法名- 同上
引用构造方法
- 格式
类名::new
- 范例
Student::new
- Stream流中 collect(Collector collector) 终结方法中的collect(Collectors.toList()) 中的toList方法底层原理
- 在底层其实就是通过方法引用创建ArrayList对象和引用LIst中的add方法将每个元素添加到ArrayList中
public static <T> Collector<T, ?, List<T>> toList() {
return new CollectorImpl<>(ArrayList::new, List::add, (left, right) -> { left.addAll(right); return left;}, CH_ID);
}
使用类名引用成员方法
-
独有的规则
- 需要有函数式接口
- 被引用的方法必须存在
- 被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致
- 被引用的方法的功能需要满足当前需求
-
抽象方法形参的详解
- 第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
- 在Stream流当中,第一个参数一般都表示流里面的每一个数据
- 假设流里面的数据都是字符串,那么使用这种方式进行方法引用,只能引用String这个类中的方法
- 第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要时无参的成员方法
- 第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
-
格式
类名::成员方法
-
范例
String::substring
-
局限性
- 不能引用所有类中的成员方法
- 是跟抽象方法的第一个参数类型有关,这个参数是什么类型的,那么就只能引用这个类中的方法
引用数组的构造方法
- 格式
数据类型[]::new
- 范例
int[]::new
练习
- 集合中存储一些字符串的数据,比如"张三,23",收集到Student类型的数组中,使用方法引用完成
- 创建集合添加学生对象,学生对象属性:name,age,只获取姓名并放到数组,中使用方法引用完成
- 创建集合添加学生对象,学生对象属性:name,age,把姓名年龄拼接成,"张三-23"的字符串,并放到数组当中,使用方法引用完成
//标准javabean
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String s) {
this.name = s.split(",")[0];
this.age = Integer.parseInt(s.split(",")[1]);
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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 String toString() {
return this.name + "-" + this.age;
}
}
//test1
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三,23", "李四,24", "王五,25");
Student[] arr = list.stream()
.map(Student::new)
.toArray(Student[]::new);
for (Student student : arr) {
System.out.println(student);
}
}
//test2
public static void main(String[] args) {
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 24);
Student s3 = new Student("王五", 25);
ArrayList<Student> list = new ArrayList<>();
Collections.addAll(list, s1, s2, s3);
String[] arr = list.stream()
.map(Student::getName)
.toArray(String[]::new);
for (String s : arr) {
System.out.println(s);
}
}
//test3
public static void main(String[] args) {
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 24);
Student s3 = new Student("王五", 25);
ArrayList<Student> list = new ArrayList<>();
Collections.addAll(list, s1, s2, s3);
String[] arr = list.stream()
.map(Student::toString)
.toArray(String[]::new);
for (String s : arr) {
System.out.println(s);
}
}