.1 方法引用介绍
方法引用:把已经存在的方法拿过来用,当做函数式接口中抽象方法的方法体
方法引用符 是 ::
方法引用是需要注意
- 需要有函数式接口
- 被引用方法必须已经存在
- 被引用方法的形参和返回值需要跟抽象方法保持一致
- 被引用方法的功能要满足当前的需求
.2 方法引用的分类
.2.1 引用静态方法
类名::静态方法
public class FunctionDemo1 {
public static void main(String[] args){
Integer[] arr = {1,2,35,4,3,6,11,8,9,7};
//方法引用
//引用处需要是函数式接口
//被引用的方法要已经存在 第三方或者Java提供 或者自己编写的
//被引用方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
//被引用的方法的功能需要满足当前需求
//表示引用FunctionDemo1类里面的subtraction方法
//把这个方法当作抽象方法的方法体
Arrays.sort(arr,FunctionDemo1::subtraction);
for (Integer integer : arr) {
System.out.println(integer);
}
System.out.println("---------------------------------------");
}
//数组中的数据实现倒序
public static int subtraction(Integer o1,Integer o2){
return o2-o1;
}
}
.2.2 引用成员方法
.2.2.1 引用其他类的成员方法
其它类对象::方法名
public class FunctionDemo3 {
public static void main(String[] args){
//引用成员方法
ArrayList<String> list1 = new ArrayList<>();
list1.add("张山");
list1.add("张三丰");
list1.add("道一");
list1.add("剑一");
list1.add("张无忌");
//找出张开头的 stream流+lambda表达式
list1.stream()
.filter(s ->s.startsWith("张"))
.forEach(s->System.out.println(s));
System.out.println("---------------------------------------");
//匿名内部类
list1.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张");
}
});
//改成方法引用 普通成员方法要用对象来调用 静态的不能直接来调用普通成员方法
//其他类
list1.stream()
.filter(new StringOperation()::startWith)
.forEach(s->System.out.println(s));
System.out.println("---------------------------------------");
}
}
public class StringOperation {
public boolean startWith(String s){
return s.startsWith("张");
}
}
.2.2.2 引用本类的成员方法
this::方法名
注:如果再静态方法中需要使用本类类对象才能调用方法名
public class FunctionDemo3 {
public static void main(String[] args){
//引用成员方法
ArrayList<String> list1 = new ArrayList<>();
list1.add("张山");
list1.add("张三丰");
list1.add("道一");
list1.add("剑一");
list1.add("张无忌");
//找出张开头的
//本类 静态方法中没有this 只能创建成员对象 因为main是静态方法
// 不是静态方法就是this::startWith
list1.stream()
.filter(new FunctionDemo3()::startWith)
.forEach(s->System.out.println(s));
System.out.println("---------------------------------------");
}
public boolean startWith(String s){
return s.startsWith("张");
}
}
.2.2.3 引用父类的成员方法
super::方法名
.2.3 引用构造方法
类名::new
public class FunctionDemo4 {
public static void main(String[] args){
ArrayList<String>list = new ArrayList<>();
Collections.addAll(list,"张无忌,15","周芷若,14","赵敏,13","张强,20");
//Stream流
Stream<Student> studentStream = list.stream().map(new Function<String, Student>() {
@Override
public Student apply(String s) {
String[] arr = s.split(",");
return new Student(arr[0], Integer.parseInt(arr[1]));
}
});
studentStream.forEach(s->System.out.println(s));
//引用构造方法
Stream<Student> studentStream1 = list.stream().map(Student::new);
studentStream1.forEach(s->System.out.println(s));
}
}
public class Student {
private String name;
private Integer age;
public Student() {
}
//FunctionDemo4里面的引用构造方法
public Student(String s) {
String[] arr = s.split(",");
this.name = arr[0];
this.age = Integer.parseInt(arr[1]);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return name+"-"+age ;
}
}
.2.4 其他调用方法
.2.4.1 使用类名引用成员方法
类名::成员方法
public class FunctionDemo5 {
public static void main(String[] args){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"aaa","bbb","ccc","ddd");
//使用类名::方法引用
//规则:
//1.需要有函数式接口
//2.被引用的方法必须已经存在
//3.被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保证一致
//4.被引用的方法功能能满足要求
//局限性
// 不能引用所有类中的成员方法
// 是跟抽象方法的第一个参数有关,这个参数是什么类型的,那么就只能引用这个类中的方法
//拿着流里面的每一个数据去调用String类中的toUpperCase方法,方法的返回值就是转换之后的结果
//变成大写后输出
list.stream().map(String::toUpperCase).forEach(s->System.out.println(s));
//正常使用stream流
//抽象方法形参的详解
//第一个参数 表示被引用方法的调用者,决定了可以引用哪些类中的方法
// 在stream流当中,第一个参数一般都表示流里面的每一个数据
// 假设流里面的数字都是字符串,那么使用这种方式进行方法引用只能用String类型的方法 就是要和流中的数据保证类型一致
//第二个到最后一个参数都要跟引用方法的形参保持一致,如果抽象方法只有第一个参数,那么方法引用需要是无参的成员方法
list.stream().map(new Function<String, String>() {
@Override
//抽象方法 第一个形参是String类型 只能通过String::方法名去进行类名::方法名的方法引用,其他类名不可
public String apply(String s) {
return s.toUpperCase(Locale.ROOT);
}
}).forEach(s -> System.out.println(s));
}
}
.2.4.2 引用数组的构造方法
数据类型[]::new
public class FunctionDemo6 {
public static void main(String[] args){
//引用数组的构造方法
//数组的类型要跟数据流中的数据类型保持一致
//将集合中的数据存到数组中
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,1,2,3,4,5,6,7,8,9);
//引用数组的构造方法
Integer[] array = list.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(array));
//正常stream流
Integer[] arr1 = list.stream().toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});
System.out.println(Arrays.toString(arr1));
}
}