菜鸟之路Day13一一方法引用

简介: ### 菜鸟之路Day13——方法引用作者:blue 日期:2025.1.31本文介绍了Java中的方法引用,它是对Stream流的优化,简化了代码结构。方法引用可以用于静态方法、成员方法和构造方法。通过将已有方法作为函数式接口的实现,减少了匿名内部类和Lambda表达式的冗余。文中通过多个实例演示了方法引用的应用场景,包括倒序排序、字符串转换、集合过滤及对象构造等操作,帮助读者更好地理解和使用这一特性。

菜鸟之路Day13一一方法引用

作者:blue

时间:2025.1.31

0.概述

内容学习至黑马程序员BV1yW4y1Y7Ms,方法引用感觉是对Stream流的一个优化,让stream流可以更加简介,如果多个匿名内部类都要使用同一种方法,那么方法引用在此处也大有用处。

1.方法引用

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

要求:1.引用处必须是函数式接口;

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

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

​ 4.被引用方法的功能要满足当前要求

1.1方法引用初体验

public class Test1 {
   
    public static void main(String[] args) {
   
        //要求倒序排序
        Integer[] arr = {
   1,2,3,4,5,6,7,8,9};

        //匿名内部类
        /*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;
            }
        );*/

        //方法引用
        //表示引用Test类中的cmp方法
        //把这个方法当作抽象方法的方法体
        Arrays.sort(arr,Test1::cmp);

        System.out.println(Arrays.toString(arr));
    }
    public static int cmp(int a,int b){
   
        return b-a;
    }
}

1.2引用静态方法

格式:类名::静态方法

范例:Integer::parseInt

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

public class Test2 {
   
    public static void main(String[] args) {
   
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"1","2","3","4","5");

        //原来Stream流的做法
        /*list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                int i = Integer.parseInt(s);
                return i;
            }
        });*/

        //map这个位置是一个函数式接口,我们在Integer里面正好有对应的方法,所以我们可以使用方法引用
        //1.方法需要已经存在
        //2.方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
        //3.方法的功能需要把形参的字符串转换成整数
        list.stream().map(Integer::parseInt).forEach(s-> System.out.println(s));

    }
}

1.3引用成员方法

格式:对象::成员方法

①其他类:其他类对象::方法名

(注意以下两种引用本类和父类的方法,在引用处不能是静态方法,因为在静态方法中是没有this和super关键字的)

②本类:this::方法名

③父类:super::方法名

练习1:①其他类:其他类对象::方法名

public class Test3 {
   
    public static void main(String[] args) {
   
        /*需求:集合中有一些名字,按照要求过滤
        * 数据:"张无忌","周芷若","赵敏","张强","张三丰"
        * 要求:只要以张开头,而且名字是3个字的*/

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰");

        //原来Stream流的写法
        //list.stream().filter(name->name.startsWith("张")).filter(name->name.length()==3).forEach(name-> System.out.println(name));

        //成匿名内部类,可以内部的方法抽象成一个类
        /*list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("张")&&s.length()==3;
            }
        }).forEach(s-> System.out.println(s));*/

        //利用引用成员方法,①其他类:其他类对象::方法名
        list.stream().filter(new StringOperation()::test).forEach(s -> System.out.println(s));
    }
}

1.4引用构造方法

格式:类名::new

范例:Student::new

public class Test4 {
   
    public static void main(String[] args) {
   
        //需求:集合里面存储姓名和年龄,要求封装成Student对象并收集到List集合中
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"xz,22","xm,20","xt,21","xl,21","xw,18","xn,19");

        //封装成Student对象并收集到List集合中
        //String->Student,做的是类型转换所以调用map方法
        //Stream流的做法
        /*List<Student> newList = list.stream().map(new Function<String, Student>() {
            @Override
            public Student apply(String s) {
                String[] arr = s.split(",");
                String name = arr[0];
                int age = Integer.parseInt(arr[1]);
                return new Student(name, age);
            }
        }).collect(Collectors.toList());

        System.out.println(newList);*/

        //利用方法引用中的,引用构造方法
        //在Student类中新增一个匹配的构造方法
        List<Student> newList = list.stream().map(Student::new).collect(Collectors.toList());

        System.out.println(newList);
    }
}

Student的javabean类,要有对应的方法

package practice;

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

    public Student() {
   
    }

    //在Student类中新增一个符合要求的构造方法
    public Student(String s) {
   
        String[] arr = s.split(",");
        String name = arr[0];
        int age = Integer.parseInt(arr[1]);
        this.name = name;
        this.age = age;
    }

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

1.5其他调用方式

①使用类名引用成员方法

格式:类名::成员方法

范例:String::substring

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

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

        //Stream流的方法
        /*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));
    }
}

②引用数组的构造方法

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

范例:int[]::new

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

public class Test6 {
   
    public static void main(String[] args) {
   
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5,6,7,7,8);

        //stream流的方式:
        /*Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
            @Override
            public Integer[] apply(int value) {
                return new Integer[value];
            }
        });*/

        //方法引用的方式
        //数组的类型,需要和流中数据类型要保持一致
        Integer[] array = list.stream().toArray(Integer[]::new);
        System.out.println(Arrays.toString(array));
    }
}

1.6方法引用练习

练习1:集合中存储一些字符串数据,比如:"张三,23"

收集到Student类型的数组中。(在这个类型中,所使用的javabean类,)

public class practice1 {
   
    public static void main(String[] args) {
   
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"xz,22","xm,20","xt,21","xl,21","xw,18","xn,19");

        //先用中间方法map将对象类型转为Student,再利用终结方法toArray变成数组
        Student[] arr = list.stream().map(Student::new).toArray(Student[]::new);

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

练习2:创建集合添加学生对象,学生对象属性:name,age

只获取姓名放到数组当中

(Student类中新增的方法)

public String apply(Student student) {
   
        return student.getName();
}
public class practice2 {
   
    public static void main(String[] args) {
   
        ArrayList<Student> list = new ArrayList<>();
        Student stu1 = new Student("xz",21);
        Student stu2 = new Student("xw",26);
        Student stu3 = new Student("xn",20);
        Collections.addAll(list,stu1,stu2,stu3);


        /*list.stream().map(new Function<Student, String>() {
            @Override
            public String apply(Student student) {
                return student.getName();
            }
        });*/

        //将匿名内部类中获取部分数据的方法抽象为Student的一个成员方法,然后利用其他类对象::方法名类型的方法引用
        String[] arr = list.stream().map(new Student()::apply).toArray(String[]::new);
        System.out.println(Arrays.toString(arr));
    }
}

练习3:创建集合,添加学生对象,学生对象属性:name,age

把姓名和年龄拼接成:"张三-23"的字符串,并放到数组当中(使用方法引用完成)

(写在Student类中的静态方法)

 public static String test(Student student) {
   
        //搞一个链式编程
        return new StringBuilder().append(student.getName()).append("-").append(student.getAge()).toString();
    }
public class practice3 {
   
    public static void main(String[] args) {
   
        ArrayList<Student> list = new ArrayList<>();
        Student stu1 = new Student("xz",21);
        Student stu2 = new Student("xw",26);
        Student stu3 = new Student("xn",20);
        Collections.addAll(list,stu1,stu2,stu3);

        /*list.stream().map(new Function<Student, String>() {
            @Override
            public String apply(Student student) {
                //搞一个链式编程
                return new StringBuilder().append(student.getName()).append("-").append(student.getAge()).toString();
            }
        });*/

        //将上述apply方法抽象成student类中的一个静态方法,使用(类名::成员方法)的方式来拼接字符串
        String[] arr = list.stream().map(Student::test).toArray(String[]::new);
        System.out.println(Arrays.toString(arr));
    }
}
目录
相关文章
|
25天前
|
供应链 监控 安全
对话|企业如何构建更完善的容器供应链安全防护体系
阿里云与企业共筑容器供应链安全
171357 14
|
28天前
|
供应链 监控 安全
对话|企业如何构建更完善的容器供应链安全防护体系
随着云计算和DevOps的兴起,容器技术和自动化在软件开发中扮演着愈发重要的角色,但也带来了新的安全挑战。阿里云针对这些挑战,组织了一场关于云上安全的深度访谈,邀请了内部专家穆寰、匡大虎和黄竹刚,深入探讨了容器安全与软件供应链安全的关系,分析了当前的安全隐患及应对策略,并介绍了阿里云提供的安全解决方案,包括容器镜像服务ACR、容器服务ACK、网格服务ASM等,旨在帮助企业构建涵盖整个软件开发生命周期的安全防护体系。通过加强基础设施安全性、技术创新以及倡导协同安全理念,阿里云致力于与客户共同建设更加安全可靠的软件供应链环境。
150300 32
|
1月前
|
弹性计算 人工智能 安全
对话 | ECS如何构筑企业上云的第一道安全防线
随着中小企业加速上云,数据泄露、网络攻击等安全威胁日益严重。阿里云推出深度访谈栏目,汇聚产品技术专家,探讨云上安全问题及应对策略。首期节目聚焦ECS安全性,提出三道防线:数据安全、网络安全和身份认证与权限管理,确保用户在云端的数据主权和业务稳定。此外,阿里云还推出了“ECS 99套餐”,以高性价比提供全面的安全保障,帮助中小企业安全上云。
201980 15
对话 | ECS如何构筑企业上云的第一道安全防线
|
2天前
|
Linux iOS开发 MacOS
deepseek部署的详细步骤和方法,基于Ollama获取顶级推理能力!
DeepSeek基于Ollama部署教程,助你免费获取顶级推理能力。首先访问ollama.com下载并安装适用于macOS、Linux或Windows的Ollama版本。运行Ollama后,在官网搜索“deepseek”,选择适合你电脑配置的模型大小(如1.5b、7b等)。通过终端命令(如ollama run deepseek-r1:1.5b)启动模型,等待下载完成即可开始使用。退出模型时输入/bye。详细步骤如下图所示,轻松打造你的最强大脑。
1192 68
|
9天前
|
机器学习/深度学习 自然语言处理
Deepseek开源R1系列模型,纯RL助力推理能力大跃升!
近期Deepseek正式发布 DeepSeek-R1,并同步开源模型权重。DeepSeek-R1 遵循 MIT License,允许用户通过蒸馏技术借助 R1 训练其他模型。
|
5天前
|
人工智能 JavaScript 前端开发
白嫖 DeepSeek ,低代码竟然会一键作诗?
宜搭低代码平台接入 DeepSeek AI 大模型能力竟然这么方便!本教程将揭秘宜搭如何快速接入 DeepSeek API,3 步打造专属作诗机器人,也许你还能开发出更多有意思的智能玩法,让创意在代码间自由生长。
641 11
|
3天前
|
Linux iOS开发 MacOS
DeepSeek爆火,如何免费部署到你的电脑上?获取顶级推理能力教程来了
如何在本地电脑上免费部署DeepSeek,获取顶级推理能力?只需三步:1. 访问Ollama官网下载并安装对应操作系统的版本(支持macOS、Linux和Windows)。2. 打开Ollama并确保其正常运行。3. 在Ollama官网搜索并选择DeepSeek模型(如deepseek-r1),根据电脑配置选择合适的模型大小(1.5B至671B)。通过终端命令(如ollama run deepseek-r1:1.5b)运行模型,即可开始使用DeepSeek进行推理。退出模型时,在终端输入/bye。更多详情请参考Ollama官方文档。
|
13天前
|
机器学习/深度学习 自然语言处理 PyTorch
深入剖析Transformer架构中的多头注意力机制
多头注意力机制(Multi-Head Attention)是Transformer模型中的核心组件,通过并行运行多个独立的注意力机制,捕捉输入序列中不同子空间的语义关联。每个“头”独立处理Query、Key和Value矩阵,经过缩放点积注意力运算后,所有头的输出被拼接并通过线性层融合,最终生成更全面的表示。多头注意力不仅增强了模型对复杂依赖关系的理解,还在自然语言处理任务如机器翻译和阅读理解中表现出色。通过多头自注意力机制,模型在同一序列内部进行多角度的注意力计算,进一步提升了表达能力和泛化性能。
|
18天前
|
存储 人工智能 安全
对话|无影如何助力企业构建办公安全防护体系
阿里云无影助力企业构建办公安全防护体系
1262 11
|
4天前
|
机器学习/深度学习 搜索推荐 PyTorch
基于昇腾用PyTorch实现传统CTR模型WideDeep网络
本文介绍了如何在昇腾平台上使用PyTorch实现经典的WideDeep网络模型,以处理推荐系统中的点击率(CTR)预测问题。
149 65