方法引用:把已有的方法拿过来用,当做函数式接口中抽象方法的方法体
方法引用符是::
注意:
1.引用处必须是函数式接口
2.被引用的方法已经存在
3.被引用方法的形参和返回值需要跟抽象方法保持一致
4.被引用方法的功能要满足当前需求
方法引用的分类:
一、引用静态方法
格式:类名::静态方法
例子:Integer::parseInt
二、引用成员方法
格式:对象::成员方法
①其他类:其他类对象::方法名
②本类:this::方法名
③父类:super::方法名
三、引用构造方法
①其他类对象::方法名
public class demo3 {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list,"张三丰","张思","李书记","账务","张喷");
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张")&&s.length()==3;
}
}).forEach(s->System.out.println(s));
//可以把上面转为方法引用
//filter里的方法是函数式接口的 满足条件1
//引用的方法已经在new Test中创建 满足条件2
//被引用方法的形参和返回值需要跟抽象方法一致 自定义设置 满足3
//被引用方法功能都是为了筛选姓张的和姓名长度为3
list.stream().filter(new Tes()::tess).forEach(s->System.out.println(s));
}
}
//下面是Tes自定义的方法
package functionDemo;
public class Tes {
public boolean tess(String s){
return s.startsWith("张")&&s.length()==3;
}
}
②本类:this::方法名③父类:super::方法名
注意:不能写在静态方法中,静态方法中没有this和super
可以看到以下情况 可以用this调用 我们这里就假设点击login这个按钮能够更改验证码,当然实际业务这种不可能,只是为了演示这个方法复用的例子,这中做法可以提高代码的独立性
login.addActionListener(this::updateRightCode);
public void updateRightCode(ActionEvent e){
//获取正确的验证码
if(login==e.getSource()){
String codeStr = CodeUtil.getCode();
rightCode.setText(codeStr);
}
}
super就是继承中使用,不再演示
方法引用构造方法
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.stream.Collectors;
public class demo5 {
public static void main(String[] args) {
ArrayList<String> list1=new ArrayList<>();
Collections.addAll(list1,"张无忌-13","周芷若-14","赵敏-15","张强-16","张三丰-15");
list1.stream().map(new Function<String,Student>() {
@Override
public Student apply(String s) {
return new Student(s.split("-")[0],Integer.parseInt(s.split("-")[1]));
}
}).forEach(s->System.out.println(s));
System.out.println("方法引用构造方法:");
list1.stream().map(Student::new).forEach(s->System.out.println(s));
}
}
Student类中的构造方法
public Student(String s){
this.name=s.split(",")[0];
this.age=Integer.parseInt(s.split("-")[1]);
}
//方法引用满足
1.map方法里的形参满足函数式接口
2.引用的方法已经存在,生成了Student构造方法
3.参数都是String s,返回值是Student对象
4.目的都是转为Student对象
四、其它调用方式
1.使用类名引用成员方法
package functionDemo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;
import java.util.function.Function;
public class demo6 {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list,"aaa","bbb","ccc","ddd");
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));
}
}
可以看到其它类调用成员方法时跟我们上面看到的方法引用的规则似乎不太一样
这里方法规则不太一样:
1. 需要有函数式接口
2.被引用的方法必须已经存在
3.被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致
4.被引用方法的功能需要满足当前需求
可以看到,第三点与之前不同
让我们来看下抽象方法形参的详解:
第一个参数:表示被引用方法的调用者,决定了可以引用那些类中的方法,在Stream流中,第一个参数一般都表示流里面的每一个数据,假设流里面的数据是字符串,那么使用这种方法引用,只能引用String这个类中的方法
第二个参数到最后一个参数,跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的构造方法
list.stream().map(new Function<String, String>() { @Override public String apply(String s) { //只有一个参数,所以被引用的方法是无参的构造方法,且流里的数据是String类型的,只能引用String类里面的方法 return s.toUpperCase(); } }).forEach(s->System.out.println(s)); public String toUpperCase() { return toUpperCase(Locale.getDefault()); }//返回值类型都是String
2.引用数组构造方法
格式:数据类型[]::new
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;
public class demo7 {
public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<>();
Collections.addAll(list,1,2,3,4,5);
Integer []arr=list.stream().toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});
Integer []arr2=list.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(arr));
}
}
标签:java,String,list,-----,引用,new,方法,public
From: https://blog.csdn.net/qq_44766305/article/details/142361442