Java基础(下)之方法引用

方法引用

把已经有的方法拿过来用,当做函数式接口中抽象方法的方法体
条件:

  1. 引用处必须是函数式接口
  2. 被引用的方法必须已经存在,且形参和返回值需要跟抽象方法保持一致
  3. 被引用方法的功能要满足当前需求

image
以数组排序为例:

package com.example.helloworld;
import java.util.*;

class Main{

    public static void main(String[] args) throws Exception{
        Integer[] arr = {7,3,5,5,6,0,8};

        //匿名内部类
        Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });

        //lambda表达式
        Arrays.sort(arr,(Integer o1,Integer o2)->{
            return o2 - o1;
        });

        //lambda表达式简化格式
        Arrays.sort(arr,(o1,o2)->o2 - o1);

        //方法引用
        Arrays.sort(arr,Main::comp);//表示引用Main类里面的comp方法,把这个方法当做抽象方法的方法体

        System.out.println(Arrays.toString(arr));
    }

    public static int comp(int num1,int num2){
        return num2 - num1;
    }
}

引用静态方法

格式:类名::静态方法

package com.example.helloworld;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collector;

class Main{

    public static void main(String[] args) throws Exception{
        ArrayList<String>list = new ArrayList<>();
        Collections.addAll(list,"1","2","3","44","555","6666");
//        list.stream()
//                .map(new Function<String, Integer>() {
//                    @Override
//                    public Integer apply(String str){
//                        return Integer.parseInt(str);
//                    }
//                })
//                .forEach(num-> System.out.println(num));
        
        list.stream()
                .map(Integer::parseInt)
                .forEach(System.out::println);
    }
}

引用成员方法

格式:对象::成员方法

  1. 其它类:其他类对象::方法名
package com.example.helloworld;
import java.util.*;

class Main{

    public static void main(String[] args) throws Exception{
        ArrayList<String>list = new ArrayList<>();
        Collections.addAll(list,"张三丰","李佳铭","张伦达","赵四","张涛");
        
//        list.stream()
//                .filter(new Predicate<String>() {
//                    @Override
//                    public boolean test(String s) {
//                        return s.length() == 3 && s.startsWith("张");
//                    }
//                })
//                .forEach(name->System.out.println(name));

        list.stream()
                .filter(new StringOperation()::check)
                .forEach(System.out::println);
    }
}

class StringOperation{
    public boolean check(String s){
        return s.length() == 3 && s.startsWith("张");
    }
}
  1. 本类:this::方法名
    注意:引用处不能是静态方法,因为静态方法没有this
  2. 父类:super::方法名
    注意:引用处不能是静态方法,因为静态方法没有this
package com.example.helloworld;
import java.util.*;
class Father{
    public void func(String str){
        System.out.println("Father's func is called!");
    }
}

class Main extends Father{

    public void main(String[] args) throws Exception{
        ArrayList<String>list = new ArrayList<>();
        Collections.addAll(list,"张三丰","李佳铭","张伦达","赵四","张涛");
//        list.stream()
//                .filter(new Predicate<String>() {
//                    @Override
//                    public boolean test(String s) {
//                        return s.length() == 3 && s.startsWith("张");
//                    }
//                })
//                .forEach(name->System.out.println(name));
        //等价于上面代码块
        list.stream()
                .filter(new StringOperation()::check)//引用其它类方法
                .forEach(System.out::println);//引用其它类方法

        list.stream()
                .forEach(this::func);//引用本类方法

        list.stream()
                .forEach(super::func);//引用父类方法
    }
    public void func(String str){
        System.out.println("Main's func is called!");
    }
}

class StringOperation{
    public boolean check(String s){
        return s.length() == 3 && s.startsWith("张");
    }
}

引用构造方法

格式:类名::new

package com.example.helloworld;
import java.util.*;
import java.util.stream.Collectors;

class Student{
    String name;
    int age;
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }
    public Student(String str){
        String[] strs = str.split(",");
        this.name = strs[0];
        this.age = Integer.parseInt(strs[1]);
    }

    @Override
    public String toString() {
        return this.name + " " + Integer.toString(this.age);
    }
}
class Main {

    public void main(String[] args) throws Exception{
        ArrayList<String>list = new ArrayList<>();
        Collections.addAll(list,"张三丰,15","李佳铭,16","张伦达,21","赵四,24","张涛,25");

//        List<Student> list1 = list.stream()
//                .map(new Function<String, Student>() {
//                    @Override
//                    public Student apply(String s) {
//                        String[] strs = s.split(",");
//                        String name = strs[0];
//                        int age = Integer.parseInt(strs[1]);
//                        return new Student(name,age);
//                    }
//                })
//                .collect(Collectors.toList());
//        System.out.println(list1);
        
        //等价于上面代码块
        List<Student> list2 = list.stream()
                .map(Student::new)//引用构造方法
                .collect(Collectors.toList());
        System.out.println(list2);
    }
}

使用类名引用成员方法

格式:类名::成员方法
独特规则:

  1. 被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致;

形参的详解:
第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法。在Stream流中,第一个参数一般表示流中的每一个数据。假设Stream中的数据是字符串,则只能引用String这个类中的方法
剩余参数:与被引用方法的形参保持一致,若没有第二个参数,说明被引用的方法需要的是无参的成员方法

package com.example.helloworld;
import java.util.*;

class Main {

    public void main(String[] args) throws Exception{
        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(System.out::println);
    }
}

引用数组的构造方法

格式:数据格式[]::new
独特规则:

  1. 数组的类型,需要和流中数据的类型保持一致。
package com.example.helloworld;
import java.util.*;

class Main {

    public void main(String[] args) throws Exception{
        ArrayList<String>list = new ArrayList<>();
        Collections.addAll(list,"aaa","bbb","ccc","ddd");

//        String[] arr1 = list.stream()
//                .toArray(size->new String[size]);
//        System.out.println(Arrays.toString(arr1));

        String[] arr2 = list.stream()
                .toArray(String[]::new);//引用数组的构造方法
        System.out.println(Arrays.toString(arr2));
    }
}
posted @ 2026-02-24 22:22  安河桥北i  阅读(2)  评论(0)    收藏  举报