方法引用
1.方法引用可以理解为把已经有的方法拿过来用,当作函数式接口中抽象方法的方法体。
2.方法引用的使用条件:
- 引用处必须是函数式接口
- 被引用的方法必须已经存在
- 被引用方法的形参和返回值需要跟抽象方法保持一致(可以自动装箱的也可以认为一致)
- 被引用方法的功能要满足当前需求
3.方法引用符:两个冒号 ::
4.方法引用的分类:
- 引用静态方法
- 引用成员方法
- 引用构造方法
- 其它调用方法
引用静态方法
1.使用说明:
格式:类名::静态方法
范例:Integer::parseInt
比如在需要将集合中的数字字符串转换成int类型时:
假定已经创建了集合list,且其中有"1","2","3","4","5"
list.stream.map(Integer::parseInt).collector(Collectors.toList());
第一,Function接口是函数式接口;
第二,Function接口中的方法apply形参是String,返回值是Integer,而Integer的parseInt的形参类型也是String,返回值类型是int,int和Integer存在自动装箱,因此也符合;
第三,想要实现的功能和parseInt是一样的,因此可以使用。
其中的 Integer::parseInt 就相当于函数式接口Fuction中抽象方法的方法体。
引用成员方法
1.使用说明:
格式:对象::成员方法
1)其他类:其它类对象::方法名(可以用已创建对象的变量名::方法名,也可以直接new 类名()::方法名)
2)本类:this::方法名(静态方法中是没有this的,因此如果在静态方法中,需要new 本类类名()::方法名)
3)父类:super::方法名(静态方法中是没有super的,因此如果在静态方法中,需要new 父类类名()::方法名)
在使用之前一定要确定方法已经存在,同时方法满足返回值,形参的数据类型与函数式接口中方法的返回值、形参的数据类型一致,以及方法的功能是满足需求的
引用构造方法
1.使用说明:
格式:类名::new
范例:Student::new
引用构造方法时,可以认为返回值就是创建的对象的类型。
有必要的时候可以重写一个构造方法,将形参对应上,把功能写成需要的内容。
其它调用方法
1.使用类名引用成员方法。
2.引用数组的构造方法。
使用类名引用成员方法
1.使用说明:
格式:类名::成员方法
范例:String::substring
一般会在Stream流中实现Function接口时使用到。
注意:使用类名引用成员方法时,需要根据当前使用数据的类型去引用对应的方法,不能引用其它类的成员方法。因此在不少情况下需要在自建类中书写相关方法。
该类引用有独有的方法引用规则,跟上述三种不完全一样:
1)需要有函数式接口;
2)被引用的方法必须已经存在;
3)被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致;
4)被引用方法的功能需要满足当前的需求。
此时需要解释一下抽象方法:
第一个参数:表示被引用方法的调用者,决定了可以引用那些类中的方法。在Stream流中, 第一个参数一般都表示流里面的每一个数据,假设流里面的数据是字符串, 那么使用这种方式进行方法引用,只能引用String这个类中的方法。
第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被 引用的方法按需要是无参的成员方法。
引用数组的构造方法
1.使用说明:
格式:数据类型[]::new
范例:int[]::new
一般会在Stream流中的toArray方法中使用到。
细节:数组的类型,需要和流中数据的类型保持一致。
/*
练习1:集合中存储一些字符串的数据,比如:张三,23
收集到Student类型的数组当中,使用方法引用完成。
练习2:创建集合添加学生对象,学生对象属性:name,age
只获取姓名并放到数组当中,使用方法引用完成。
练习3:创建集合添加学生对象,学生对象属性:name,age
把姓名和年龄拼接成:张三-23的字符串,并放到数组当中(使用方法引用完成)
*/
// 练习1
// 创建集合并添加数据
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌,15","张三丰,50","张强,20","诸葛亮,34","周瑜,32");
// 使用Stream流,将类型转换
Student[] students1 = list1.stream()
.map(Student::new)
.toArray(Student[]::new);
System.out.println(Arrays.toString(students1));
// 练习2
// 创建集合并添加数据
ArrayList<Student> list2 = new ArrayList<>();
for (Student student : students1) {
list2.add(student);
}
// 使用Stream流,将姓名放到一个数组中
String[] students2 = list2.stream()
.map(Student::getName)
.toArray(String[]::new);
System.out.println(Arrays.toString(students2));
// 练习3
// 创建集合并添加数据
ArrayList<Student> list3 = new ArrayList<>();
for (Student student : students1) {
list3.add(student);
}
// 使用Stream流,将姓名和年龄拼接成对应格式,并放到数组中
String[] students3 = list3.stream()
.map(Student::pinJie)
.toArray(String[]::new);
System.out.println(Arrays.toString(students3));
// Student中的方法pinJie
public String pinJie(Student this){
return this.name + "-" + this.age;
}