菜鸟之路Day13一一方法引用
作者:blue
时间:2025.1.31
0.概述
内容学习至黑马程序员BV1yW4y1Y7Ms,方法引用感觉是对Stream流的一个优化,让stream流可以更加简介,如果多个匿名内部类都要使用同一种方法,那么方法引用在此处也大有用处。
1.方法引用
把已经有的方法拿过来用,当作函数式接口中抽象方法的方法体
要求:1.引用处必须是函数式接口;
2.被引用的方法必须已经存在
3.被引用方法的形参和返回值需要跟抽象方法保持一致
4.被引用方法的功能要满足当前要求
1.1方法引用初体验
public class Test1 {
public static void main(String[] args) {
//要求倒序排序
Integer[] arr = {
1,2,3,4,5,6,7,8,9};
//匿名内部类
/*Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});*/
//Lambda表达式
/*Arrays.sort(arr, (Integer o1, Integer o2)->{
return o2-o1;
}
);*/
//方法引用
//表示引用Test类中的cmp方法
//把这个方法当作抽象方法的方法体
Arrays.sort(arr,Test1::cmp);
System.out.println(Arrays.toString(arr));
}
public static int cmp(int a,int b){
return b-a;
}
}
1.2引用静态方法
格式:类名::静态方法
范例:Integer::parseInt
练习:集合中有以下数字,要求把他们都变成int类型 "1" "2" "3" "4" "5"
public class Test2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"1","2","3","4","5");
//原来Stream流的做法
/*list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
int i = Integer.parseInt(s);
return i;
}
});*/
//map这个位置是一个函数式接口,我们在Integer里面正好有对应的方法,所以我们可以使用方法引用
//1.方法需要已经存在
//2.方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
//3.方法的功能需要把形参的字符串转换成整数
list.stream().map(Integer::parseInt).forEach(s-> System.out.println(s));
}
}
1.3引用成员方法
格式:对象::成员方法
①其他类:其他类对象::方法名
(注意以下两种引用本类和父类的方法,在引用处不能是静态方法,因为在静态方法中是没有this和super关键字的)
②本类:this::方法名
③父类:super::方法名
练习1:①其他类:其他类对象::方法名
public class Test3 {
public static void main(String[] args) {
/*需求:集合中有一些名字,按照要求过滤
* 数据:"张无忌","周芷若","赵敏","张强","张三丰"
* 要求:只要以张开头,而且名字是3个字的*/
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰");
//原来Stream流的写法
//list.stream().filter(name->name.startsWith("张")).filter(name->name.length()==3).forEach(name-> System.out.println(name));
//成匿名内部类,可以内部的方法抽象成一个类
/*list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张")&&s.length()==3;
}
}).forEach(s-> System.out.println(s));*/
//利用引用成员方法,①其他类:其他类对象::方法名
list.stream().filter(new StringOperation()::test).forEach(s -> System.out.println(s));
}
}
1.4引用构造方法
格式:类名::new
范例:Student::new
public class Test4 {
public static void main(String[] args) {
//需求:集合里面存储姓名和年龄,要求封装成Student对象并收集到List集合中
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"xz,22","xm,20","xt,21","xl,21","xw,18","xn,19");
//封装成Student对象并收集到List集合中
//String->Student,做的是类型转换所以调用map方法
//Stream流的做法
/*List<Student> newList = list.stream().map(new Function<String, Student>() {
@Override
public Student apply(String s) {
String[] arr = s.split(",");
String name = arr[0];
int age = Integer.parseInt(arr[1]);
return new Student(name, age);
}
}).collect(Collectors.toList());
System.out.println(newList);*/
//利用方法引用中的,引用构造方法
//在Student类中新增一个匹配的构造方法
List<Student> newList = list.stream().map(Student::new).collect(Collectors.toList());
System.out.println(newList);
}
}
Student的javabean类,要有对应的方法
package practice;
public class Student {
private String name;
private int age;
public Student() {
}
//在Student类中新增一个符合要求的构造方法
public Student(String s) {
String[] arr = s.split(",");
String name = arr[0];
int age = Integer.parseInt(arr[1]);
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
1.5其他调用方式
①使用类名引用成员方法
格式:类名::成员方法
范例:String::substring
练习:集合里面一些字符串,要求变成大写后进行输出
public class Test5 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"aaa","bbb","ccc","ddd");
//Stream流的方法
/*list.stream().map(new Function<String, String>() {
@Override
public String apply(String s) {
return s.toUpperCase();
}
}).forEach(s-> System.out.println(s));*/
//方法引用,使用类名引用成员方法
list.stream().map(String::toUpperCase).forEach(s-> System.out.println(s));
}
}
②引用数组的构造方法
格式:数据类型[]::new
范例:int[]::new
练习:集合中存储一些整数,收集到数组当中
public class Test6 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,1,2,3,4,5,6,7,7,8);
//stream流的方式:
/*Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});*/
//方法引用的方式
//数组的类型,需要和流中数据类型要保持一致
Integer[] array = list.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(array));
}
}
1.6方法引用练习
练习1:集合中存储一些字符串数据,比如:"张三,23"
收集到Student类型的数组中。(在这个类型中,所使用的javabean类,)
public class practice1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"xz,22","xm,20","xt,21","xl,21","xw,18","xn,19");
//先用中间方法map将对象类型转为Student,再利用终结方法toArray变成数组
Student[] arr = list.stream().map(Student::new).toArray(Student[]::new);
System.out.println(Arrays.toString(arr));
}
}
练习2:创建集合添加学生对象,学生对象属性:name,age
只获取姓名放到数组当中
(Student类中新增的方法)
public String apply(Student student) {
return student.getName();
}
public class practice2 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
Student stu1 = new Student("xz",21);
Student stu2 = new Student("xw",26);
Student stu3 = new Student("xn",20);
Collections.addAll(list,stu1,stu2,stu3);
/*list.stream().map(new Function<Student, String>() {
@Override
public String apply(Student student) {
return student.getName();
}
});*/
//将匿名内部类中获取部分数据的方法抽象为Student的一个成员方法,然后利用其他类对象::方法名类型的方法引用
String[] arr = list.stream().map(new Student()::apply).toArray(String[]::new);
System.out.println(Arrays.toString(arr));
}
}
练习3:创建集合,添加学生对象,学生对象属性:name,age
把姓名和年龄拼接成:"张三-23"的字符串,并放到数组当中(使用方法引用完成)
(写在Student类中的静态方法)
public static String test(Student student) {
//搞一个链式编程
return new StringBuilder().append(student.getName()).append("-").append(student.getAge()).toString();
}
public class practice3 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
Student stu1 = new Student("xz",21);
Student stu2 = new Student("xw",26);
Student stu3 = new Student("xn",20);
Collections.addAll(list,stu1,stu2,stu3);
/*list.stream().map(new Function<Student, String>() {
@Override
public String apply(Student student) {
//搞一个链式编程
return new StringBuilder().append(student.getName()).append("-").append(student.getAge()).toString();
}
});*/
//将上述apply方法抽象成student类中的一个静态方法,使用(类名::成员方法)的方式来拼接字符串
String[] arr = list.stream().map(Student::test).toArray(String[]::new);
System.out.println(Arrays.toString(arr));
}
}