定义:把已经存在的方法拿过来用,当做函数式接口中的抽象方法的方法体。
方法引用符 ::
注意点:需要有函数式接口;被引用方法必须存在;被引用方法的形参和返回值需要跟抽象方法保持一致;被引用方法的功能要满足当前的需求。
public class test {
public static void main(String [] args) {
//创建一个数组,进行倒序排序
Integer[] arr= {5,4,8,9,1,3};
//先用匿名内部类
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(Arrays.toString(arr));
//lambda表达式
Arrays.sort(arr, ( o1, o2)-> o2-o1);
System.out.println(Arrays.toString(arr));
//方法引用
Arrays.sort(arr,test::subtract);
System.out.println(Arrays.toString(arr));
}
public static int subtract(int num1,int num2) {
return num2-num1;
}
}
方法引用类型:
1)引用静态方法
public class test {
public static void main(String [] args) {
//把集合中的数据,转成int类型
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list, "1","2","3","4","5");
list.stream().map(new Function<String,Integer>() {//原先使用的方法
@Override
public Integer apply(String t) {
int i=Integer.parseInt(t);
return i;
}
})
.forEach(s->System.out.print(s));
System.out.println("--------");
//利用方法引用
list.stream().map(Integer::parseInt).forEach(s->System.out.println(s));
}
}
2)引用成员方法
1.引用其他类对象
格式:其他类对象::方法名
package test02;
public class Operate {
public boolean select(String t){
return t.startsWith("张")&&t.length()==3;
}
}
public class test {
public static void main(String [] args) {
//把集合中有一些名字,要求过滤,以张开头,且长度为3
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list, "张客栈","柳树底","张丽","吴明奇","张晓明");
//先用匿名内部类看看是否为函数式接口
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String t) {
return t.startsWith("张")&&t.length()==3;
}
})
.forEach(s->System.out.println(s));
System.out.println("--------");
//用方法引用,要满足题目要求
//建立一个类,在这个类中写方法
list.stream().filter(new Operate()::select).forEach(s->System.out.println(s));
}
}
2.引用本类或父类的成员方法
本类:this::方法 父类:super::方法名
静态方法中没有this和super。
3)引用构造方法
格式:类名::new
package test02;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String str) {//str为流中的数据
this.name=str.split(",")[0];
this.age=Integer.parseInt(str.split(",")[1]);
}
public Student(String name,int age) {
this.setName(name);
this.setAge(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 + "]";
}
}
public class test {
public static void main(String [] args) {
//把集合中有一些名字
//把数据封装成Student对象并收集到List集合中
//封装就是转换类型(利用map)
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list, "张客栈,25","柳树底,22","张丽,21","吴明奇,26","张晓明,30");
//原先方法
/* List<Student> l=list.stream().map(new Function<String, Student>() {
@Override
public Student apply(String t) { //方法引用中的方法要和这个方法类似
String name=t.split(",")[0];
int age=Integer.parseInt(t.split(",")[1]);
return new Student(name,age);
}
})
.collect(Collectors.toList());
System.out.println(l);
*/
//利用方法引用
List<Student>l2=list.stream().map(Student::new).collect(Collectors.toList());
System.out.println(l2);
}
}
4)使用类名引用成员方法
格式:类名::成员方法
仅限这种方法的规则:
public class test {
public static void main(String [] args) {
//集合里面的字符串,要求变成大写后输出
//变成大写:其实也是将String->String
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list, "aaa","bbb","ccc","ddd","eee");
list.stream().map(new Function<String, String>() { //匿名内部类
@Override
public String apply(String t) {
return t.toUpperCase();
}
})
.forEach(s->System.out.println(s));
System.out.println("-----------");
//引用方法
list.stream().map(String::toUpperCase).forEach(s->System.out.println(s));
}
}
5)引用数组的构造方法
格式:数据类型【】::new
数组的类型,需跟流中数据的类型保持一致。
public class test {
public static void main(String [] args) {
//集合中存储一些整数,收集到数组中。
ArrayList<Integer> list=new ArrayList<>();
Collections.addAll(list, 1,2,3,4,8,5);
Integer[] arr1=list.stream().toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});
System.out.println(Arrays.toString(arr1));
//使用引用方法
Integer[] arr2= list.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(arr2));
}
}
综合练习
练习1:
集合中存储一些字符串的数据, 比如:张三,23。
收集到Student类型的数组当中( 使用方法引用完成)
package test02;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String str) {//str为流中的数据
this.name=str.split(",")[0];
this.age=Integer.parseInt(str.split(",")[1]);
}
public Student(String name,int age) {
this.setName(name);
this.setAge(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 + "]";
}
}
public class test {
public static void main(String [] args) {
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list, "张三,23","王五,25","李四,24");
Student[] arr= list.stream().map(Student::new).toArray(Student[]::new);
System.out.println(Arrays.toString(arr));
}
}
练习2:
创建集合添加学生对象,学生对象属性: name, age
只获取姓名并放到数组当中(使用方法引用完成)
public class test {
public static void main(String [] args) {
ArrayList<Student> list=new ArrayList<>();
list.add(new Student("zhangsan",23));
list.add(new Student("lisi",24));
list.add(new Student("wangwu",25));
//将Student转为String
String[] arr=list.stream().map(Student::getName).toArray(String[]::new);
System.out.println(Arrays.toString(arr));
/*
String[] arr= list.stream().map(new Function<Student, String>() {
@Override
public String apply(Student t) {
return t.getName();
}
}).toArray(String[]::new);
System.out.println(Arrays.toString(arr));
*/
}
}