Java中的方法引用

本文介绍了Java中的方法引用,包括如何引用静态方法、成员方法以及构造方法。通过示例展示了如何在函数式接口中使用方法引用,简化代码并提高可读性。例如,使用Integer::parseInt将字符串转换为整数,以及通过类名::new引用构造方法创建对象。
摘要由CSDN通过智能技术生成

概念:通俗来讲,就是把已经有的方法拿过来用,当作函数式接口中抽象方法的方法体

使用规则:

1、引用处必须是函数式接口

2、被引用的方法必须已经存在

3、被引用的方法的形参和返回值需要跟抽象方法保持一致

4、被引用方法的功能要满足当前需求

符号:"::"

一、引用静态方法:

格式:类名 : : 静态方法

Integer::parseInt

例:

public class FunctionDemo1 {
    public static void main(String[] args) {
        /*
        集合中有以下数字,要求把它们全变成int型
        list={"1","2","3","4","5"};
         */
        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(System.out::println);
        //1
        //2
        //3
        //4
        //5

        //使用方法引用的代码
        list.stream().map(Integer::parseInt)
                .forEach(System.out::println);
        //1
        //2
        //3
        //4
        //5


    }
}




二、引用成员方法:

格式:对象 : : 成员方法

1、其他类:其它类对象 : : 方法名

2、本类:this : : 方法名

3、父类:super : : 方法名

 例 1:其他类的引用

public class FunctionDemo2 {
    public static void main(String[] args) {
        /*
        集合中有一些名字,按照要求过滤数据
        数据:"张三二","张五","赵六","李四","张麻子"
        要求:以张字开头,且名字是三个字的
         */

        
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三二", "张五", "赵六", "李四", "张麻子");

        //未使用方法引用
        list.stream().filter(s -> s.startsWith("张"))
                .filter(s -> s.length()==3)
                .forEach(System.out::println);
        //张三二
        //张麻子

        //使用方法引用
        list.stream().filter(new StringOperation()::stringJudge)
                .forEach(System.out::println);
        //张三二
        //张麻子
    }
}


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


 例 2:本类的引用

//未使用方法引用之前
public class LoginJFrame extends JFrame implements ActionListener {
    public LoginJFrame(){

        initJFrame();
        
        initView();
        
        this.setVisible(true);
    }

    JButton go=new JButton("Go");
    private void initView() {
        JLabel image=new JLabel();
        image.setBounds(100,50,174,174);
        image.setBackground(Color.red);
        this.getContentPane().add(image);

        
        go.setFont(new Font(null,1,20));
        go.setBounds(120,274,150,50);
        go.setBackground(Color.WHITE);

        go.addActionListener(this);

        this.getContentPane().add(go);


    }

    private void initJFrame() {
        this.setTitle("...");
        this.setSize(480,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setLayout(null);
        this.getContentPane().setBackground(Color.white);
        this.setAlwaysOnTop(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object obj=e.getSource();
        if(obj == go){
            System.out.println("被点击");
        }
    }
}

在点击Go之后,控制台会输出“被点击字样”

使用方法引用后:

//使用方法引用后
public class LoginJFrame extends JFrame {
    public LoginJFrame(){

        initJFrame();
        
        initView();
        
        this.setVisible(true);
    }

    JButton go=new JButton("Go");
    private void initView() {
        JLabel image=new JLabel();
        image.setBounds(100,50,174,174);
        image.setBackground(Color.red);
        this.getContentPane().add(image);


        go.setFont(new Font(null,1,20));
        go.setBounds(120,274,150,50);
        go.setBackground(Color.WHITE);

        //注意这块有区别:
        go.addActionListener(this::method);

        this.getContentPane().add(go);


    }

    private void initJFrame() {
        this.setTitle("...");
        this.setSize(480,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setLayout(null);
        this.getContentPane().setBackground(Color.white);
        this.setAlwaysOnTop(true);
    }

    public void method(ActionEvent e) {
        Object obj=e.getSource();
        if(obj == go){
            System.out.println("被点击");
        }
    }
}

最后结果相同 

例 3:父类的引用 

public class LoginJFrame extends MyJFrame{
    public LoginJFrame(){

        initJFrame();
        
        initView();
        
        this.setVisible(true);
    }

    JButton go=new JButton("Go");
    private void initView() {
        JLabel image=new JLabel();
        image.setBounds(100,50,174,174);
        image.setBackground(Color.red);
        this.getContentPane().add(image);


        go.setFont(new Font(null,1,20));
        go.setBounds(120,274,150,50);
        go.setBackground(Color.WHITE);

        //这里有区别
        go.addActionListener(super::method);

        this.getContentPane().add(go);


    }

    private void initJFrame() {
        this.setTitle("...");
        this.setSize(480,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setLayout(null);
        this.getContentPane().setBackground(Color.white);
        this.setAlwaysOnTop(true);
    }


}


public class MyJFrame extends JFrame {
    public void method(ActionEvent e) {
        System.out.println("被点击");
    }
}




 最后输出结果相同

三、引用构造方法

格式:类名 : : new 

例 1:

public class Demo1 {
    public static void main(String[] args) {
        /*
        集合里面存储姓名和年龄,比如: 张无忌,15
        要求: 将数据封装成Student对象并收集到List集合中
         */
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三,15", "李四,16", "王五,17");

        //未引用构造方法
        List<Student> newList = list.stream()
                .map(s -> new Student
                        (s.split(",")[0],
                                Integer.parseInt(s.split(",")[1])))
                .collect(Collectors.toList());
        System.out.println(newList);
        //[Student{name = 张三, age = 15}, Student{name = 李四, age = 16}, Student{name = 王五, age = 17}]


        //引用构造方法
        List<Student> newList2 = list.stream().map(Student::new)
                .collect(Collectors.toList());
        System.out.println(newList2);
        //[Student{name = 张三, age = 15}, Student{name = 李四, age = 16}, Student{name = 王五, age = 17}]
    }
}



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

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //切割字符串并把对应的数据交到对象中
    public Student(String s) {
        this.name=s.split(",")[0];
        this.age=Integer.parseInt(s.split(",")[1]);
    }

    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;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}

四、其他调用方式

1、使用类名引用成员方法

格式:类名 : : 成员方法

例:

public class StringDemo2 {
    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(System.out::println);
        //AAA
        //BBB
        //CCC
        //DDD

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

    }
}

 方法引用的规则:

        1、需要有函数式接口

        2、被引用的方法必须已经存在

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

        4、被引用方法的功能需要满足当前的需求

抽象方法形参详解:

第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法

                     在Stream流当中,第一个参数一般都表示流里面的每一个数据

第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的

方法需要是无参的成员方法                    

2、引用数组的构造方法

格式:数据类型 [ ] : : new 

例:

public class Demo2 {
    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));
        //[1, 2, 3, 4, 5]
        System.out.println(Arrays.toString(arr2));
        //[1, 2, 3, 4, 5]

    }
}



觉得有用就点点赞把~

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值