方法引用概述
把已经有的东西拿过来用,当做函数式接口中的抽象方法的方法体
import java.util.*;
public class test {
public static void main(String[] args) {
//需求:创建一个数组,进行倒序排列
Integer[] arr = {3,5,4,1,6,2};
//匿名内部类
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(Arrays.toString(arr));//[6, 5, 4, 3, 2, 1]
System.out.println("--------------------");
//lambda表达式
//因为第二个参数的类型Comparator是一个函数式接口
Arrays.sort(arr,(Integer o1,Integer o2)->{
return o2 - o1;
});
System.out.println(Arrays.toString(arr));
System.out.println("---------------------");
//lambda表达式简化格式
Arrays.sort(arr,(o1,o2)->o2-o1);
System.out.println(Arrays.toString(arr));
System.out.println("---------------------");
//方法引用
//1.引用处必须是函数式接口
//2.被引用的方法需要已经存在
//3.被引用方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
//4.被引用方法的功能需要满足当前的要求
//表示引用test类里面的subtraction方法
//把这个方法当做抽象方法的方法体
Arrays.sort(arr,test::subtraction);
System.out.println(Arrays.toString(arr));
}
//可以是java已经写好的,也可以是一些第三方工具类
public static int subtraction(int num1,int num2){
return num2-num1;
}
}
引用静态方法
import java.util.*;
import java.util.function.Function;
public class test {
public static void main(String[] args) {
//1.创建集合并添加元素
ArrayList<String>list = new ArrayList<>();
Collections.addAll(list,"1","2","3","4","5");
//2.常规方法
// ArrayList<Integer>list2 = new ArrayList<>();
// for (String s : list) {
// int i = Integer.parseInt(s);
// list2.add(i);
// }
list.stream().map(new Function<String, Integer>() {//要把这个数据转成什么类型
@Override
public Integer apply(String s) {
int i = Integer.parseInt(s);
return i;
}
}).forEach(s-> System.out.println(s));
//1.方法需要已经存在
//2.方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
//3.方法的功能需要把形参的字符串转换成整数
list.stream().map(Integer::parseInt).forEach(s-> System.out.println(s));
}
}
引用其他类的成员方法
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Predicate;
public class test {
public static void main(String[] args) {
/*
需求:
集合中有一些名字,按照要求过滤数据
数据:"张无忌","周芷若","赵敏","张强","张三丰"
要求:只要以张开头,而且名字是3个字的
*/
//1.创建集合
ArrayList<String>list = new ArrayList<>();
//2.添加数据
Collections.addAll(list,"张无忌","周芷若","赵敏","张三丰");
//3.过滤数据(只要以张开头,而且名字是3个字的)
// list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(s-> System.out.println(s));
// list.stream().filter(new Predicate<String>() {
// @Override
// public boolean test(String s) {
//
// return s.startsWith("张")&&s.length()==3;
// }
// }).forEach(s-> System.out.println(s));
// /*
// 其他类
// */
// StringOperation so = new StringOperation();
// list.stream().filter(so::StringJudge)
// .forEach(s-> System.out.println(s));
//静态方法中是没有this的
//但是如果在静态中可以直接本类对象引用方法
list.stream().filter(new test()::StringJudge)
.forEach(s-> System.out.println(s));
}
public boolean StringJudge(String s){
return s.startsWith("张")&&s.length()==3;
}
}
引用本类或父类的成员方法
练习2:这个学了GUI可以自己写写
引用构造方法
目的:创建这个类的对象
所以再写一个只有一个参数的构造方法
public class Student{
private String name;
private int age;
public Student() {
}
public Student(String str){//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;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class test {
public static void main(String[] args) {
//1.创建集合对象
ArrayList<String>list = new ArrayList<>();
//2.添加数据
Collections.addAll(list,"张无忌,15","周芷若,14","赵敏,13","张强,20","张三丰,100","张翠山,40","张良,35","王二麻子,37");
//3.封装Student对象并收集到List集合中
//String --> Student
// 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);
List<Student> newlist2 = list.stream().map(Student::new).collect(Collectors.toList());
System.out.println(newlist2);
}
}
类名引用成员方法
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Function;
public class test {
public static void main(String[] args) {
/*
类名引用成员方法的规则:
1.需要有函数式接口
2.被引用的方法必须已经存在
3.被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值保持一致
4.被引用方法的功能需要满足当前的需求
抽象方法形参的详解:
第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
在Stream流当中,第一个参数一般都是表示流里面的每一个数据
假设流里面的数据是字符串,那么使用这种方法进行方法引用,只能引用String这个类的方法
第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法
局限性:不能引用所有类中的成员方法
是跟抽象方法的第一个参数有关,这个参数是什么类型的,那么就只能引用这个类中的方法.
*/
//1.创建集合对象
ArrayList<String>list = new ArrayList<>();
//2.添加数据
Collections.addAll(list,"aaa","bbb","ccc","ddd");
//3.变成大写之后进行输出
// 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));
//map(String::toUpperCase)
//拿着流里面的每一个数据,去调用String类中的toUpperCase方法,方法的返回值就是转换之后的结果
}
}
引用数组的构造方法
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;
public class test {
public static void main(String[] args) {
//1.创建集合并添加元素
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,1,2,3,4,5);
/*
细节 :
数组的类型,需要跟流中数据的类型保持一致
*/
Integer[] arr2 = list.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(arr2));
//2.收集到数组当中
// Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
// @Override
// public Integer[] apply(int value) {
// return new Integer[value];
// }
// });
//3.打印
// System.out.println(Arrays.toString(arr);
}
}
练习
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Function;
public class test {
public static void main(String[] args) {
/*
技巧:
1.现在有没有一个方法符合我当前的需求
2.如果有这样的方法,这个方法能否满足引用的规则
静态 类名 :: 方法名
成员方法 类名::方法名 对象名:方法名 this. super.
构造方法 类名 ::new
*/
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("aaa",1));
list.add(new Student("bbb",2));
list.add(new Student("ccc",3));
String[] arr = list.stream().map(new Function<Student, String>() {
@Override
public String apply(Student student) {
return student.getName()+"-"+student.getAge();
}
}).toArray(String[]::new);
System.out.println(Arrays.toString(arr));
}
}