Java—— 方法引用 : :

发布于:2025-05-17 ⋅ 阅读:(21) ⋅ 点赞:(0)

方法引用是什么

把已经存在的方法拿过来用,当做函数式接口中抽象方法的方法体

方法引用符

::

方法引用的条件

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

方法引用的分类

引用静态方法

格式:类名 : : 静态方法
范例: Integer : : parseInt

代码演示

集合中有以下数字,要求把他们都变成int类型
“1”,“2”,“3”,“4”,”5“ 

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;

public class Test1 {
    public static void main(String[] args) {

        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 s) {
                        return Integer.parseInt(s);
                    }
                })
                .forEach(s -> System.out.println(s));

        //lambda表达式
        list.stream()
                .map(s -> Integer.parseInt(s))
                .forEach(s -> System.out.println(s));

        //方法引用类型
        //map中是函数式接口
        //Integer类中的parseInt静态方法符合
        //形参和返回值与抽象方法一致
        //功能满足当前的需求
        //因此可以进行方法引用
        list.stream()
                .map(Integer::parseInt)
                .forEach(s -> System.out.println(s));
        //1
        //2
        //3
        //4
        //5
    }
}

引用成员方法

基本格式:对象 : : 成员方法 

引用本类或父类的成员方法

本类:this : : 方法名

父类:super : : 方法名

注:因为this和super处的方法不是静态的,因此引用处也不能是静态 

代码演示

设置一个界面,上面有两个按钮,对按钮利用方法引用的形式添加动作监听,要求涉及本类中的方法和父类中的方法

App类

public class App {
    public static void main(String[] args) {
        new LoginJFrame();
    }
}

LoginJFrame类继承MyJFrame

import javax.swing.*;
import java.awt.event.ActionEvent;

public class LoginJFrame extends MyJFrame {

    JButton go1;
    JButton go2;

    public LoginJFrame() {

        //初始化界面
        initFrame();

        //定义按钮组件
        go1 = new JButton("go(本类)");
        go1.setBounds(180, 80, 150, 50);
        this.getContentPane().add(go1);

        go2 = new JButton("go(父类)");
        go2.setBounds(30, 80, 150, 50);
        this.getContentPane().add(go2);

        //除了实现接口外
        //还可以利用方法引用给按钮设置动作监听
        go1.addActionListener(this::method1);//本类中的go被点击了
        go2.addActionListener(super::method2);//父类中的go被点击了
    }


    public void method1(ActionEvent e) {
        System.out.println("本类中的go被点击了");
    }

    //定义方法初始化界面
    private void initFrame() {
        //设置大小
        this.setSize(400, 300);
        //设置置顶
        this.setAlwaysOnTop(true);
        //设置居中
        this.setLocationRelativeTo(null);
        //设置关闭模式
        this.setDefaultCloseOperation(3);
        //设置解除默认居中放置,使用坐标决定组件位置
        this.setLayout(null);
        //设置界面可视
        this.setVisible(true);
    }

}

 MyJFrame类继承JFrame

import javax.swing.*;
import java.awt.event.ActionEvent;

public class MyJFrame extends JFrame {
    public void method2(ActionEvent e) {
        System.out.println("父类中的go被点击了");
    }
}
引用其他类的成员方法

格式:其他类对象 : : 方法名

代码演示

集合中有一些名字,按照要求过滤数据
数据:"张无忌","周芷若","赵敏","张强","张三丰"
要求:只要以张开头,而且名字是3个字的 

测试类

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Predicate;

public class Test {
    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));

        //lambda表达式
        list.stream()
                .filter(s -> s.startsWith("张") && s.length() == 3)
                .forEach(s -> System.out.println(s));

        //方法引用
        //需要先在别的类(StringOperation)中定义一个方法(stringJudge)
        //使得该方法
        //形参和返回值需跟抽象方法一致
        //功能满足当前的需求
        list.stream()
                .filter(StringOperation::stringJudge)
                .forEach(s -> System.out.println(s));
        //张无忌
        //张三丰
    }
}

 StringOperation 类

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

引用构造方法

格式:类名 : : new
范例:student : : new

代码演示

集合里面存储姓名和年龄,比如:张三,23
要求:将数据封装成Student对象并收集到List集合中 

测试类 

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) {

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三,23", "李四,24", "王五,25");

        //匿名内部类
        List<Student> newList1 = list.stream()
                .map(new Function<String, Student>() {
                    @Override
                    public Student apply(String s) {
                        return new Student(s.split(",")[0],
                                Integer.parseInt(s.split(",")[1]));
                    }
                }).collect(Collectors.toList());

        //lambda表达式
        List<Student> newList2 = list.stream()
                .map(s -> new Student(s.split(",")[0],
                        Integer.parseInt(s.split(",")[1])))
                .collect(Collectors.toList());


        //方法引用
        List<Student> newList3 = list.stream()
                .map(Student::new)
                .collect(Collectors.toList());
        System.out.println(newList3);
        //[Student{name='张三', age=23}, Student{name='李四', age=24}, Student{name='王五', age=25}]

    }
}

Student类

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    //定义一个构造方法
    //形参和返回值跟抽象方法一致
    //功能要满足当前的需求
    public Student(String s){
        this.name = s.split(",")[0];
        this.age = Integer.parseInt(s.split(",")[1]);
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = 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 +
                '}';
    }
}

其他引用方式

使用类名引用成员方法

格式:类名 : : 成员方法
范例:String : : substring

此方法引用有不同的规则:
1.需要有函数式接口
2.被引用的方法必须已经存在
3.被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致。
4.被引用方法的功能需要满足当前的需求

抽象方法形参的详解:
第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
在Stream流当中,第一个参数一般都表示流里面的每一个数据。假设流里面的数据是字符串,那么使用这种方式进行方法引用,只能引用String这个类中的方法
第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法  

弊端:

不能引用所有类中的成员方法,若抽象方法的第一个参数是A类型的,只能引用A类中的方法 

代码演示

集合里面一些字符串,要求变成大写后进行输出 

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;

public class Test1 {
    public static void main(String[] args) {

        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(s -> System.out.println(s));

        //lambda表达式
        list.stream()
                .map(s -> s.toUpperCase())
                .forEach(s -> System.out.println(s));

        //方法引用
        list.stream()
                .map(String::toUpperCase)
                .forEach(s -> System.out.println(s));
        //AAA
        //BBB
        //CCC

    }
}
引用数组的构造方法 

格式:数据类型[ ] : : new
范例:int[ ] : : new

代码演示

集合中存储一些整数,收集到数组当中 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;

public class Test2 {
    public static void main(String[] args) {

        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 1, 2, 3, 4, 5);

        //匿名内部类
        Integer[] arr1 = list.stream()
                .toArray(new IntFunction<Integer[]>() {
                    @Override
                    public Integer[] apply(int value) {
                        return new Integer[value];
                    }
                });

        //lambda表达式
        Integer[] arr2 = list.stream()
                .toArray(value -> new Integer[value]);

        //方法引用
        Integer[] arr3 = list.stream()
                .toArray(Integer[]::new);

        System.out.println(Arrays.toString(arr1));
        System.out.println(Arrays.toString(arr2));
        System.out.println(Arrays.toString(arr3));
        //[1, 2, 3, 4, 5]
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到