方法引用 
更新: 2025/4/9 字数: 0 字 时长: 0 分钟
一、方法引用概述 
更新: 2025/4/9 字数: 0 字 时长: 0 分钟
1、概述 
方法引用使用条件 
- 1、引用处必须是函数式接口
 - 2、被引用的方法需要已存在(可以是java写好的,也可以是第三方的工具类)
 - 3、被引用的形参和返回值需要跟抽象方法的形参和返回值保持一致
 - 4、被引用的方法的功能需要满足当前的要求
 



2、示例代码 
java
package com.pyw.a47function;
import java.util.Arrays;
import java.util.Comparator;
public class FunctionDemo1 {
    public static void main(String[] args) {
        //TODO 需求:创建一个数组,进行倒序排列
        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));
        //Lambda表达式简化格式
        Arrays.sort(arr,(o1,o2) -> o2-o1);
        System.out.println(Arrays.toString(arr));
        //方法引用
        //1、引用处必须是函数式接口
        //2、被引用的方法需要已存在(可以是java写好的,也可以是第三方的工具类)
        //3、被引用的形参和返回值需要跟抽象方法的形参和返回值保持一致
        //4、被引用的方法的功能需要满足当前的要求
        //表示引用FunctionDemo1类里面的subAbstract方法
        //把这个方法当作抽象方法的方法体
        //::方法引用符
        Arrays.sort(arr,FunctionDemo1::subAbstract);
        System.out.println(Arrays.toString(arr));
    }
    public static int subAbstract(int num1,int num2){
        return num1 - num2;
    }
}二、方法引用的分类 
更新: 2025/4/9 字数: 0 字 时长: 0 分钟

1、引用静态方法 

java
package com.pyw.a47function;
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
public class FunctionDemo2 {
    public static void main(String[] args) {
        /*
            方法引用(引用静态方法)
            格式
                类::方法名
            需求:
                集合中又一下数字,要求把他们都变成int类型
                "1","2","3","4","5"
         */
        //1.创建集合并添加元素
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"1","2","3","4","5");
        //2.把他们都变成int类型
        //匿名内部类
        list.stream().map(new Function<String, Object>() {
            @Override
            public Object apply(String s) {
                return Integer.parseInt(s);
            }
        }).forEach(s -> System.out.println(s));
        //方法引用
        //方法引用
        //1、引用除必须是函数式接口
        //2、被引用的方法需要已存在(可以是java写好的,也可以是第三方的工具类)
        //3、被引用的形参和返回值需要跟抽象方法的形参喝返回值保持一致
        //4、被引用的方法的功能需要满足当前的要求
        System.out.println("====方法引用====");
        list.stream()
                .map(Integer::parseInt)
                .forEach(s -> System.out.println(s));
    }
}2、引用成员方法 

(1)引用其他类的方法 

①示例代码 

java
package com.pyw.a47function;
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Predicate;
public class FunctionDemo3 {
    public static void main(String[] args) {
        /*
        方法引用(引用成员方法)
        格式
         *       静态  类名::方法名
         *       成员方法 在哪儿?
         *              如果流里面时Student类型,并且方法再Student方法当中 类名::方法名
         *              如果方法在其他类 对象名::方法名
         *              如果方法在本类   this::方法名
         *              如果方法在父类   super::方法名
         *       构造方法  类名::new
        需求:
            集合中有一些名字,按照要求过滤数据
            数据:"张无忌","周芷若","赵敏","张强","张三丰"
            要求:只要以张开头,而且名字是3个字的
       */
        //1.创建集合
        ArrayList<String> list = new ArrayList<>();
        //2.添加数据
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰");
        //3.过滤数据(只要张开头的数据而且名字是3个字的)
        //lambda
        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::stringJudege)
                .forEach(s -> System.out.println(s));
        //方法引用(本类成员方法)
        //静态方法中是没有this的- main方法是静态方法无法调用本类中的非静态方法。
        list.stream().filter(new FunctionDemo3()::stringJudege) //通过new本类的对象z再调用本类的方法
                .forEach(s-> System.out.println(s));
    }
    //非静态方法可能通过this::方法名,调用本类的成员方法
    public void test(ArrayList<String> list){
        //方法引用(本类成员方法)
        list.stream()
                .filter(this::stringJudege)
                .forEach(s -> System.out.println(s));
    }
    public boolean stringJudege(String s){
        return s.startsWith("张") && s.length() ==3;
    }
}StringOperation类:
java
package com.pyw.a47function;
public class StringOperation {
    public boolean stringJudege(String s){
        return s.startsWith("张") && s.length() ==3;
    }
}(2)引用本类的方法 

注意:
- 静态方法中是没有this的-比如 main方法是静态方法无法调用本类中的非静态方法。 
- 只能通过new本类的对象再调用本类的方法
 
 - 非静态方法可能通过this::方法名,调用本类的成员方法
 
①示例代码 
如果在本类中有一个成员方法,我们可以使用 this::方法名 进行方法引用。例如:
java
@FunctionalInterface
interface MyFunction {
    void execute(String msg);
}
public class MethodReferenceDemo {
    public void printMessage(String message) {
        System.out.println("本类方法: " + message);
    }
    public void testMethodReference() {
        MyFunction func = this::printMessage; // 引用本类方法
        func.execute("Hello from this::printMessage");
    }
    public static void main(String[] args) {
        new MethodReferenceDemo().testMethodReference();
    }
}输出:
本类方法: Hello from this::printMessage(3)引用父类的方法 

①示例代码 
在子类中,我们可以使用 super::方法名 来引用父类的成员方法。例如:
java
@FunctionalInterface
interface MyFunction {
    void execute(String msg);
}
class Parent {
    public void showMessage(String message) {
        System.out.println("父类方法: " + message);
    }
}
public class Child extends Parent {
    public void testMethodReference() {
        MyFunction func = super::showMessage; // 引用父类方法
        func.execute("Hello from super::showMessage");
    }
    public static void main(String[] args) {
        new Child().testMethodReference();
    }
}输出:
父类方法: Hello from super::showMessage3、引用构造方法 

①示例代码 
java
package com.pyw.a47function;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class FunctionDemo4 {
    public static void main(String[] args) {
        /*
        方法引用(引用构造方法)
        格式
                类名::new
        目的:
                创建这个类的对象
        需求:
             集合里面存储姓名和年龄,要求封装成Student对象并收集到List集合中
        方法引用的规则:
            1.需要有函数式接口
            2.被引用的方法必须已经存在
            3.被引用方法的形参和返回值,需要跟抽象方法的形参返回值保持一致
            4.被引用方法的功能需要满足当前的需求
            
       */
        //1.创建集合对象
        ArrayList<String> list = new ArrayList<>();
        //2.添加数据
        Collections.addAll(list, "张无忌,15", "周芷若,14", "赵敏,13", "张强,20", "张三丰,100", "张翠山,40", "张良,35", "王二麻子,37", "谢广坤,41");
        //3.封装成Student对象到List集合中
        List<Student> students = list.stream().map(Student::new).collect(Collectors.toList());
        System.out.println(students);
    }
}学生对象-Student
java
public class Student {
    private String name;
    private int age;
    //参数含义为:接收stream流里面的数据对象
    public Student(String str) {
        String[] arr = str.split(",");
        this.name = arr[0];
        this.age = Integer.parseInt(arr[1]);
    }
}4、其他调用方式 

(1)使用类名引用其他成员方法 
①**注意:** 
和引用其他类的方法的==区别==:
- 对象::方法名,要求被引用方法的形参,需要跟抽象方法的形参完全一致
 - 类名::方法名,只需要被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致
 
方法引用的规则:
- 1.需要又函数式接口
 - 2.被引用的方法必须已经存在
 - 3.被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致
 - 4.被引用的功能需要满足当前的需求
 
抽象方法详解:
- 第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
 - 再Stream流中,第一个参数一般都表示流里面的每一个数据。
 - 架设流里面的数据是字符串,那么这种方式进行方法引用,只能引用String这个类中的方法
 - 第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法
 
局限性:
- 不能引用所有类中的成员方法。
 - 是跟抽象方法的第一个参数有关,这个参数是什么类型的,那么就只能引用这个类中的方法。
 
②示例代码 
java
package com.pyw.a47function;
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
public class FunctionDemo5 {
    public static void main(String[] args) {
        /*
            方法引用(类名引用成员方法)
            语法:
                类名::成员方法
            集合里面添加字符串,变成大写后再输出
            方法引用的规则:
            1.需要又函数式接口
            2.被引用的方法必须已经存在
            3.被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致
            4.被引用的功能需要满足当前的需求
            抽象方法详解:
            第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
                        再Stream流中,第一个参数一般都表示流里面的每一个数据。
                        架设流里面的数据是字符串,那么这种方式进行方法引用,只能引用String这个类中的方法
            局限性:
            不能引用所有类中的成员方法。
            是跟抽象方法的第一个参数有关,这个参数是什么类型的,那么就只能引用这个类中的方法。
         */
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"aaa","bbb","ccc");
        //匿名内部类
        list.stream().map(new Function<String, String>() {
            @Override
            public String apply(String s) { //抽象方法的第一个参数
                return s.toUpperCase();
            }
        }).forEach(System.out::println);
        list.stream()
                //拿着流里面的每一个数据,去调用String类中的toUpperCase方法,方法的返回值就是转换之后的结果。
                .map(String::toUpperCase)
                .forEach(System.out::println);
    }
}(2)引用数组的构造方法 

①细节 
- 数组的类型,需要跟流中数据的类型保持一致。
 
②示例代码 
java
package com.pyw.a47function;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;
public class FunctionDemo6 {
    public static void main(String[] args) {
        /*
        方法引用(数组的构造方法)
        格式
                数据类型[]::new
        目的:
                创建一个指定类型的数组
        需求:
             集合中存储一些整数,收集到数组当中
        细节:
            数组的类型,需要跟流中数据的类型保持一致。
       */
        //1.创建集合并添加元素
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 1, 2, 3, 4, 5);
        //2.收集到数组当中
        //匿名内部类
        Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
            @Override
            public Integer[] apply(int value) {
                //value表示集合长度
                return new Integer[value];
            }
        });
        System.out.println(Arrays.toString(arr));
        //方法引用
        Integer[] arr2 = list.stream().toArray(Integer[]::new);
        System.out.println(Arrays.toString(arr2));
    }
}三、技巧 
更新: 2025/4/9 字数: 0 字 时长: 0 分钟
技巧:
- 1.现在有没有一个方法符合我当前的需求
 - 2.如果有这样的方法,这个方法是否满足引用的规则 
- 静态方法 类名::方法名
 - 成员方法 在哪儿? 
- 如果流里面时Student类型,并且方法在Student方法当中 类名::方法名
 - 如果方法在其他类 对象名::方法名
 - 如果方法在本类 this::方法名
 - 如果方法在父类 super::方法名
 
 - 构造方法 类名::new
 
 
四、小结 
更新: 2025/4/9 字数: 0 字 时长: 0 分钟


五、练习 
更新: 2025/4/9 字数: 0 字 时长: 0 分钟

1、练习1 
java
package com.pyw.a47function;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Function;
public class FunctionTest1 {
    public static void main(String[] args) {
        /*
        需求:
             集合中存储一些字符串的数据,比如:张三,23。
             收集到Student类型的数组当中
       */
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌,15", "周芷若,14", "赵敏,13", "张强,20", "张三丰,100", "张翠山,40", "张良,35", "王二麻子,37", "谢广坤,41");
        //2.先把字符串变成Student对象,然后再把Student对象收集起来
        Student[] students = list.stream()
                //注意使用stream转换时需要重写Student的构造方法,让他与map方法中需要重写的方法保持一致
                .map(Student::new)
                //创建新数组接收student
                .toArray(Student[]::new); //数组的类型,需要跟流中数据的类型保持一致
        System.out.println(Arrays.toString(students));
    }
}Student类
java
public Student(String str) {
    String[] arr = str.split(",");
    this.name = arr[0];
    this.age = Integer.parseInt(arr[1]);
}2、练习2 
java
package com.pyw.a47function;
import java.util.ArrayList;
import java.util.Arrays;
public class FunctionTest2 {
    public static void main(String[] args) {
        /*
         *   需求:
         *       创建集合添加学生对象
         *       学生对象属性:name,age
         *   要求:
         *       获取姓名并放到数组当中
         *       使用方法引用完成
         *
         *   技巧:
         *       1.现在有没有一个方法符合我当前的需求
         *       2.如果有这样的方法,这个方法是否满足引用的规则
         *       静态   类名::方法名
         *       成员方法 在哪儿?
         *              如果流里面时Student类型,并且方法在Student方法当中 类名::方法名
         *              如果方法在其他类 对象名::方法名
         *              如果方法在本类   this::方法名
         *              如果方法在父类   super::方法名
         *       构造方法  类名::new
         *
         *
         * */
        //1.创建集合
        ArrayList<Student> list = new ArrayList<>();
        //2.添加元素
        list.add(new Student("zhangsan",23));
        list.add(new Student("lisi",24));
        list.add(new Student("wangwu",25));
        String[] strings = list.stream().map(Student::getName) //流中的数据类型 已经Student-》String
            .toArray(String[]::new); //数组的类型,需要跟流中数据的类型(此时是String)保持一致
        System.out.println(Arrays.toString(strings));
    }
}3、练习3 
java
package com.pyw.a47function;
import java.util.ArrayList;
import java.util.Arrays;
public class FunctionTest3 {
    public static void main(String[] args) {
        /*
         *   需求:
         *       创建集合添加学生对象
         *       学生对象属性:name,age
         *   要求:
         *       把姓名和年龄拼接成:张三-23的字符串,并放到数组当中
         *       使用方法引用完成
         * */
        ArrayList<Student> list2 = new ArrayList<>();
        list2.add(new Student("zhangsan",23));
        list2.add(new Student("lisi",24));
        list2.add(new Student("wangwu",25));
        String[] strings = list2.stream().map(Student::toString).toArray(String[]::new);
        System.out.println(Arrays.toString(strings));
    }
}
