Java进阶之旅第七天
文章目录
方法引用
介绍
- 把已经有的方法拿过来用,当做函数式接口中抽象方法的方法体
- 满足条件
- 1.引用处必须是函数式接口
- 2.被引用的方法必须已经存在
- 3.被引用方法的形参和返回值需要跟抽象方法保持一致
- 4.被引用方法的功能要满足当前需求
- 方法引用符: ‘::’
- 引用方法需要使用类调用方法
代码展示
//简单演示(将数组逆序排序
Integer[] arr = {1,2,3,4,5,6,7,8};
// 1.引用处必须是函数式接口(Arrays.sort的第二个参数)
// 2.被引用的方法必须已经存在(存在compareTo
// 3.被引用方法的形参和返回值需要跟抽象方法保持一致
// 4.被引用方法的功能要满足当前需求
Arrays.sort(arr,Main::compareTo);
System.out.println(Arrays.toString(arr));
}
public static int compareTo(int a,int b){
return b-a;
}
结果
[8, 7, 6, 5, 4, 3, 2, 1]
方法引用的分类
引用静态方法
格式
类名::静态方法
- 例子:
Integer::parseInt
代码
// 1.引用处必须是函数式接口(Arrays.sort的第二个参数)
// 2.被引用的方法必须已经存在(存在compareTo
// 3.被引用方法的形参和返回值需要跟抽象方法保持一致
// 4.被引用方法的功能要满足当前需求
ArrayList<String> arr = new ArrayList<>();
Collections.addAll(arr,"1","2","3");
//将字符串转化成Int类型
//利用上一天学习过的stream流,中的map(类型转换,具有函数式接口
//将字符串转化成Int类型,利用Integer类中的parseInt方法,并且用静态方法引用
Integer[] newarr = arr.stream().map(Integer::parseInt).toArray(value -> new Integer[value]);
System.out.println(Arrays.toString(newarr));
结果
[1, 2, 3]
引用成员方法
格式
对象::成员方法
- 细节:
- 其他类:
其他类对象::方法名
- 本类:
this::方法名
(引用处不能是静态的,原因: 静态不存在this) - 父类:
super::方法名
(引用处不能是静态的)
- 其他类:
代码:
// 1.引用处必须是函数式接口
// 2.被引用的方法必须已经存在
// 3.被引用方法的形参和返回值需要跟抽象方法保持一致
// 4.被引用方法的功能要满足当前需求
ArrayList<String> arr = new ArrayList<>();
Collections.addAll(arr,"小明","校长","小红");
//要求: 筛选姓"小",且名字长度为2的字符串
//以前的写法
/*arr.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("小")&&s.length()==2;
}
}).forEach(s-> System.out.println(s));*/
//成员方法引用
/*
* stringJudge类存在judge方法
* */
arr.stream().filter(new stringJudge()::judge).forEach(System.out::println);
///stringJudge类的代码
public boolean judge(String s){
return s.startsWith("小")&&s.length()==2;
}
结果
小明
小红
引用构造方法
格式/目的
- 格式:
类名::new
- 例子:
Student::new
- 目的: 创建对象
代码:
// 1.引用处必须是函数式接口
// 2.被引用的方法必须已经存在
// 3.被引用方法的形参和返回值需要跟抽象方法保持一致
// 4.被引用方法的功能要满足当前需求
ArrayList<String> arr = new ArrayList<>();
Collections.addAll(arr,"小明-15","校长-50","小红-16");
/*目的
* 将集合中的名字和年龄封装到People对象并收集到List集合中
* */
//不使用lambda简化的操作
/*List<People> Parr = arr.stream().map(new Function<String, People>() {
@Override
public People apply(String s) {
String name = s.split("-")[0];
int age = Integer.parseInt(s.split("-")[1]);
return new People(name, age);
}
}).toList();
System.out.println(Parr);*/
//使用引用构造函数
List<People> Parr = arr.stream().map(People::new).toList();
System.out.println(Parr);
///People中的关键构造方法
//在People类中添加的构造函数
//不需要返回值
public People(String s) {
this.name = s.split("-")[0];
this.age = Integer.parseInt(s.split("-")[1]);
}
结果:
[People{name = 小明, age = 15}, People{name = 校长, age = 50}, People{name = 小红, age = 16}]
使用类名引用成员方法
格式
类名::成员方法
- 例子:
String::substring
独有规则
- 方法引用的规则:
- 1.需要有函数式接口
- 2.被引用的方法必须已经存在
- 3.被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致。
- 4.被引用方法的功能需要满足当前的需求
- 抽象方法形参的详解:
- 第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法,在Stream流当中,第一个参数一般都表示流里面的每一个数据。假设流里面的数据是字符串,那么使用这种方式进行方法引用,只能引用String这个类中的方法
- 第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法
代码
ArrayList<String> arr = new ArrayList<>();
Collections.addAll(arr,"a","b","c");
//转大写
arr.stream().map(String::toUpperCase).forEach(System.out::println);
结果
A
B
C
引用数组的构造方法
格式
数据类型[]::new
- 例子:
int[]::new
- 创建数组的类型需要和元素的类型保持一致
代码
ArrayList<Integer> arr = new ArrayList<>();
Collections.addAll(arr,1,2,3,4);
//集合数据转到数组中
/*Integer[] array = arr.stream().toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});*/
Integer[] array = arr.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(array));
结果
[1, 2, 3, 4]