目录
一、 内容概述
二、方法引用的分类
1. 引用静态方法
2. 引用成员方法
2.1 引用其他类的成员方法
2.2 引用本类或父类的成员方法
3. 引用构造方法
4. 其他调用方法
4.1 类名引用成员方法
4.2 引用数组的构造方法
三、 方法引用综合小练习
1. 转为自定义对象并且收集到数组
2. 获取部分属性并收集到数组
方法引用可以拆分为方法和引用两方面:
方法引用:把已经有的方法拿过来用,当作函数接口中抽象方法的方法体。
:: (方法引用符)
但是要注意: 并不是所有的方法都可以直接引用,需要满足以下四种条件
- 引用处必须是函数式接口
- 被引用的方法必须已经存在
- 被引用方法的形参和返回值必须和抽象方法保持一致
- 被引用方法的功能要满足当前需求
public class FunctionDemo {
public static void main(String[] args) {
// 需求: 床技术组,进行倒序排列
Integer[] arr = { 3, 5, 4, 1, 6, 2 };
// 通过层层递进 进一步学习方法引用
//匿名内部类
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Integer o1,Integer o2) {
return o2 -o1;
}
});
System.out.println(Arrays.toString(arr));
//lambda表达式
//因为第二个参数的类型Comparator是一个函数式接口
Arrays.sort(arr, (Integer o1,Integer o2) -> {
return o2 - o1;
});
//lambda表达式简化格式
Arrays.sort(arr, (o1,o2) -> o2 - o1);
//方法引用
//1.引用处必须是函数式接口
//2.被引用的方法必须已经存在
//3.被引用方法的形参和返回值必须和抽象方法保持一致
//4.被引用方法的功能要满足当前需求
//表示引用FunctionDemo中的substraction方法
//把这个方法当作抽象方法的方法体
Arrays.sort(arr, FunctionDemo::subStraction);
System.out.println(Arrays.toString(arr));
}
//可以使Java已经写好的 ,也可以是一些第三方工具类
//静态方法 类名调用
public static int subStraction(int num1,int num2) {
return num2 - num1 ;
}
}
格式: 类名: : 静态方法
范例: Integer: : parseInt
public class FunctionTest {
public static void main(String[] args) {
//1.创建集合并添加对象
ArrayList list = new ArrayList<>();
Collections.addAll(list, "1","2","3","4","5");
//2.转变成int类型
list.stream().map(new Function() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s);
}
}).forEach(s -> System.out.println(s));
//1.方法需要已经存在
//2.方法的形参和返回值需要和抽象方法的形参和返回值保持一致
//3.方法的功能需要把形参的字符串转换为整数
//方法引用
list.stream()
.map(Integer::parseInt)
.forEach(s -> System.out.println(s));
}
}
格式:对象: :成员方法
- 其他类:其他类对象: :方法名
- 本类:this: :方法名
- 父类:super: :方法名
其他类:其他类对象: :方法名
// 其他类:StringOperation.java
public class StringOperation {
public boolean StringJudge(String s) {
return s.startsWith("张") && s.length() == 3;
}
}
public class FunctionTest {
public static void main(String[] args) {
//1.创建集合
ArrayList list =new ArrayList<>();
//2.添加数据
Collections.addAll(list, "张大三","李四","王五","赵六","张七");
//3.过滤数据
list.stream().filter(s->s.startsWith("张"))
.filter(s->s.length() == 3 )
.forEach(s->System.out.println(s)); //张大三
//lambda表达式
list.stream().filter(new Predicate() {
@Override
public boolean test(String s) {
return s.startsWith("张") && s.length() == 3;
}
}).forEach(s->System.out.println(s));
//4.方法引用
StringOperation so = new StringOperation();
list.stream().filter(so::StringJudge)
.forEach(s->System.out.println(s));
}
}
本类:this: :方法名
父类:super: :方法名
注意:引用处不能是静态方法
格式:类名: :new
范例:student: :new
练习:
集合里面存储姓名和年龄,比如:张三,23
要求:将数据封装成Student对象并收集到List集合中
public class FunctionDemo03 {
public static void main(String[] args) {
// 1.创建集合对象
ArrayList list = new ArrayList<>();
// 2.添加数据
Collections.addAll(list, "张三,23", "李四,24", "王五,25", "赵六,26");
// 3.封装成Student对象 并且收集到list集合中
List newList = list.stream()
.map(new Function() {
@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);
// 引用构造方法
List newList2 = list.stream()
.map(Student::new)
.collect(Collectors.toList());
System.out.println(newList2);
}
}
//Student.java
public class Student {
private String name;
private int age;
public Student() {}
public Student(String str) {
String[] arr = str.split(",");
this. name = arr[0];
this.age = Integer.parseInt(arr[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;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
格式:类名: :成员方法
范例:String: :subString
局限性:
- 不能引用所有类中的成员方法。
- 与抽象方法第一个参数有关,参数类型是什么那么就只能一怒用这个类中的方法。
练习:
集合里面一些字符串,要求变成大写后进行输出
public class FunctionDemo04 {
public static void main(String[] args) {
//抽象方法形参详解:
// 第一个参数: 表示被引用方法的调用者,决定了可以引用哪些类中的方法
// 在Stream流中,第一个参数一般表示流里面的每一个数据
// 假设流连的数据是字符串,那么使用这种方式进行方法引用,只能引用String这个类中的方法
//
// 第二个参数到最后一个参数: 与被引用方法的形参保持一致
// 如果没有第一个参数,说明被引用的方法需要时无参的成员方法
// 1.创建集合对象
ArrayList list = new ArrayList<>();
// 2.添加数据
Collections.addAll(list, "aaa", "bbb", "ccc", "ddd");
//3.变成大写再输出
//匿名内部类
//String --> String
list.stream().map(new Function() {
@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 FunctionDemo05 {
public static void main(String[] args) {
//细节:数组类型需要和数据类型保持一致
// 1.创建集合并添加数据
ArrayList list = new ArrayList<>();
Collections.addAll(list, 1, 2, 3, 4, 5);
//2.创建数组 数据收集到数组中
//匿名内部类
Integer[] arr = list.stream().toArray(new IntFunction() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});
System.out.println(Arrays.toString(arr));
//方法引用
Integer[] arr2 = list.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(arr2));
}
}
需求:
集合中存储一些字符串的数据,比如:张三,23。
收集到Student类型的数组当中(使用方法引用完成)
public class FunctionText {
public static void main(String[] args) {
// 1.创建集合对象
ArrayList list = new ArrayList<>();
// 2.添加数据
Collections.addAll(list, "张三,23", "李四,24", "王五,25", "赵六,26");
//3.收集到Student类型的数组中
//先把字符变成Student对象 再把Student对象收集起来
//此时流中数据是Student还是String类型呢? -> Student类型
Student[] arr =list.stream()
//先把字符变成Student对象
.map(Student::new)
//数组构造方法 -》构建数组并将数据存放进去
.toArray(Student[]::new);
System.out.println(Arrays.toString(arr));
}
}
需求:
创建集合添加学生对象,学生对象属性:name,age
只获取姓名并放到数组当中(使用方法引用完成)
public class FunctionText {
public static void main(String[] args) {
//方法引用小技巧:
//1.现在有没有一个方法符合当前需求
//2.如果有,则看这个方法是否满足引用的规则
//静态: 类名::方法名
//成员方法:本类中:类名::方法名 this
// 其他类中: 对象名::方法名 super
//构造方法:类名:: new
// 1.创建集合
ArrayList list = new ArrayList<>();
// 2.添加元素
list.add(new Student("张三", 23));
list.add(new Student("李四", 24));
list.add(new Student("王五", 25));
// 3.获取姓名添加进数组
// 匿名内部类
String[] arr = list.stream().map(new Function() {
@Override
public String apply(Student student) {
return student.getName();
}
}).toArray(String[]::new);
System.out.println(Arrays.toString(arr));
//方法引用
String[] arr2 = list.stream().map(Student::getName).toArray(String[]::new);
System.out.println(Arrays.toString(arr2));
}
}