JavaSE 面向对象程序设计高级 方法引用 2024详解

news2024/7/6 20:48:18

在编程中,方法引用(Method Reference)是一种技术,它让你能够直接引用一个现有的函数或方法,而无需通过对象实例来调用。这种方法在函数式编程和高阶函数中非常有用,因为它提供了简洁的方式来传递函数行为,使代码更加灵活和可复用。

以下是方法引用的一些特点和用法:

  1. 直接引用:你可以创建一个方法引用,它直接指向某个类的静态方法或实例方法。例如,std::sort(myVector.begin(), myVector.end(), std::greater<int>()) 中的 std::greater<int>() 就是一个函数指针类型的引用,它直接指向 greater 函数。

  2. 类型参数化:方法引用可以接收类型参数,如 [](const T& t) -> void { ... },这是一种通用的方法引用,适用于任何接受 T 类型参数的函数。

  3. Lambda表达式:Java和C++11引入了lambda表达式,它们本质上就是方法引用的简化形式,可以直接定义并使用匿名函数。

  4. 作为函数参数或返回值:方法引用可以被用作其他函数的参数,或者作为函数的返回值,这样可以使接口设计更加简洁。

 

方法 :以前学习的方法

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

引用处必须是函数接口

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

被应用的方法的形参和返回值必须要和抽象方法保持一致

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

改写

import java.util.Arrays;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        Integer arr[]={3,3,4,5,6,7};
        Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        System.out.println(Arrays.toString(arr));
    }
}

只有函数式接口能用Lambda表达式简化

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Integer arr[]={3,3,4,5,6,7};
        Arrays.sort(arr, (Integer o1,Integer o2) -> {
            return o2-o1;
        });
        System.out.println(Arrays.toString(arr));
    }
}
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Integer arr[]={3,3,4,5,6,7};
        Arrays.sort(arr, (o1,o2) -> o2-o1);
        System.out.println(Arrays.toString(arr));
    }
}

方法引用改写条件

1.引用处需要是函数式接口

2.被引用的方法需要已经存在

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

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

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Integer arr[]={3,3,4,5,6,7};
        //表示引用Main类里的subtraction方法
        //把这方法作为抽象方法的方法体
        Arrays.sort(arr, Main::subtraction);
        System.out.println(Arrays.toString(arr));
    }
    public static int subtraction(int num1,int num2){
        return num2-num1;
    }
}

小结

引用静态方法

格式

类名::静态方法

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

public class Main {
    public static void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        Collections.addAll(list,"1","2","3","4","5","6");
        //先写匿名内部类
        //自动生成方法体
        list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                int i=Integer.parseInt(s);
                return i;
            }
        }).forEach(s -> System.out.println(s));
    }
}

方法引用简化

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        Collections.addAll(list,"1","2","3","4","5","6");
        list.stream().map(Integer::parseInt).forEach(s -> System.out.println(s));
    }
}

引用成员方法

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        Collections.addAll(list,"张三","张思锐","3","4","5","6");
        list.stream().filter(s -> s.startsWith("张")).filter(s ->s.length()==3).forEach(s -> System.out.println(s));
    }
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Predicate;

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

方法引用

1.写在其他类当中

public class Judge {
    public boolean judge(String s){
        return s.startsWith("张")&&s.length()==3;
    }
}
import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        Collections.addAll(list,"张三","张思锐","3","4","5","6");
        //普通的成员方法要对象来调用
        //这里也可以先创建对象再去调用
        list.stream().filter(new Judge()::judge).forEach(s-> System.out.println(s));
    }
}

2.写在本类当中

静态方法中是没有this关键字的

因为Main默认是静态的

所以要创建本类的对象

格式 对象::成员方法

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        Collections.addAll(list,"张三","张思锐","3","4","5","6");
        //普通的成员方法要对象来调用
        //这里也可以先创建对象再去调用
        list.stream().filter(new Judge()::judge).forEach(s-> System.out.println(s));
    }
    public static boolean judge(String s){
        return s.length()==3&&s.startsWith("张");
    }
}

引用处不能是静态方法

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        Collections.addAll(list,"张三","张思锐","3","4","5","6");
        //普通的成员方法要对象来调用
        //这里也可以先创建对象再去调用
        list.stream().filter(this::judge).forEach(s-> System.out.println(s));
    }
    public boolean judge(String s){
        return s.length()==3&&s.startsWith("张");
    }
}

引用构造方法

为什么要引用构造方法

是为了创建对象

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        Collections.addAll(list,"张三,12","李四,13","王五,15");
        //封装成Student类对象,并且放到集合里面去、
        List<Student>newlist=list.stream().map(new Function<String, Student>() {
            @Override
            public Student apply(String s) {
                String arr[]=s.split(",");
                return new Student(arr[0],Integer.parseInt(arr[1]));
            }
        }).collect(Collectors.toList());
        System.out.println(newlist);
    }
}

构造方法运行完后对象就已经有了

在javabean类里写方法

注意参数类型要和调用处一致(new处)

所以在javabean类里要写一个只有一个形参的方法

Student::new

表示使用了Student类里的构造方法并获得了对象

用类名引用成员方法

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Main {
    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(s -> System.out.println(s));
    }
}

用类名引用成员方法改写

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        Collections.addAll(list,"aaa","bbb","ccc");
        list.stream().map(String::toUpperCase).forEach(s -> System.out.println(s));
    }
}

被引用方法的形参和返回值要和抽象方法中的形参和返回值一致

方法引用的规则 是类名引用成员方法独有的

需要有函数式接口

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

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

拿着流中的每一个数据去调用String类中的toUpperCase方法

方法的返回值就是转换之后的结果

局限性

不能引用所有类中的成员方法

是跟抽象方法的第一个参数(形参)有关,这个参数是什么类型的,就只能引用这个类中的方法

引用数组的构造方法

数组是没有构造方法的

但是有一个专门描述数组的类,有构造方法

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        Collections.addAll(list,"张三","李四","王五");
        String[] array = list.stream().toArray(String[]::new);
        for(String s:array)System.out.println(s);
    }
}

总结

个人号推广

博客主页

多多!-CSDN博客

Web后端开发

https://blog.csdn.net/qq_30500575/category_12624592.html?spm=1001.2014.3001.5482

Web前端开发

https://blog.csdn.net/qq_30500575/category_12642989.html?spm=1001.2014.3001.5482

数据库开发

https://blog.csdn.net/qq_30500575/category_12651993.html?spm=1001.2014.3001.5482

项目实战

https://blog.csdn.net/qq_30500575/category_12699801.html?spm=1001.2014.3001.5482

算法与数据结构

https://blog.csdn.net/qq_30500575/category_12630954.html?spm=1001.2014.3001.5482

计算机基础

https://blog.csdn.net/qq_30500575/category_12701605.html?spm=1001.2014.3001.5482

回忆录

https://blog.csdn.net/qq_30500575/category_12620276.html?spm=1001.2014.3001.5482

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1840057.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

晋升受阻或遭受不公:你想到这条路了吗?

晋升受阻或遭受不公&#xff1a;你想到这条路了吗&#xff1f; 当你在职场上遇到晋升受阻或者感觉受到不公平对待的时候&#xff0c;你一般选择怎么处理&#xff1f;是逆来顺受、忍气吞声、还是听命安排与据理力争&#xff1f; 其实并非无路可走&#xff0c;这时候&#xff0c;…

在二维空间中用椭圆表示不确定性

在二维空间中用椭圆表示不确定性 flyfish import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Ellipse# 生成示例数据 np.random.seed(0) data np.random.multivariate_normal([0, 0], [[4, 2], [2, 3]], size500)# 计算均值和协方差矩阵 …

使用node把任意网站封装为可执行文件

直接上步骤&#xff1a; 1. node.js 环境准备 下载地址 那个版本都行&#xff0c;下一步->下一步 安装即可 2. windows 系统下&#xff0c; 快捷键 winr ->输入 cmd -> 回车 3. 执行第一个命令&#xff0c;安装 nativefier 等一段时间 npm install nativefier -g 4…

GitHub爆赞!最适合新手入门的教程——笨方法学Python 3

“Python 是一门既容易上手又强大的编程语言。”这句话本身并无大碍&#xff0c;但需要注意的是&#xff0c;正因为它既好学又好用&#xff0c;所以很多 Python 程序员只用到了其强大功能的一小部分。 今天给小伙伴们分享的这份手册以习题的方式引导读者一步一步学习编程&…

VMware 虚拟机共享宿主机文件夹

一、背景 在虚拟机中&#xff0c;需要写文件到宿主机的文件系统中 宿主机的文件共享给虚拟机使用 这些场景就涉及到VM的虚拟机怎么访问宿主机的磁盘文件夹 二、软件背景 宿主机&#xff1a;window机器&#xff0c;本文是win7 虚拟软件&#xff1a;VMware12.5.6&#xff0…

js文件导出功能

效果图&#xff1a; 代码示例&#xff1a; <!DOCTYPE html> <html> <head lang"en"><meta charset"UTF-8"><title>html 表格导出道</title><script src"js/jquery-3.6.3.js"></script><st…

Office--加载宏-CS上线

免责声明:本文仅做技术交流与学习... 目录 关于宏上线的格式: 操作流程: 其他office文本的上线格式一样: 关于宏上线的格式: doc宏病毒: 1-生成格式为dotm 只要点启用宏就上线 2-生成格式为()word 97-2003 .doc) 被杀 操作流…

Qt入门小项目 | 实现一个图片查看器

文章目录 一、实现一个图片查看软件 一、实现一个图片查看软件 需要实现的功能&#xff1a; 打开目录选择图片显示图片的名字显示图片 在以上功能的基础上进行优化&#xff0c;需要解决如下问题&#xff1a; 如何记住上次打开的路径&#xff1f; 将路径保存到配置文件中&#x…

LabVIEW在SpaceX的应用

结合真实的资料介绍LabVIEW在SpaceX的应用&#xff0c;涵盖自动化测试系统、数据采集与监控、可视化与分析、模块化设计与扩展&#xff0c;以及效率与可靠性的提高。 ​ 自动化测试系统 LabVIEW在SpaceX的自动化测试系统中发挥了关键作用。自动化测试是确保SpaceX火箭及其子系…

Android焦点机制结合WMS

文章前提&#xff1a; 了解WMS基本作用了解window的概念&#xff0c;phoneWindow&#xff0c;rootViewImpl了解view的事件分发 开始&#xff1a; 讲三件事情&#xff1a; window的创建&#xff0c;更新焦点的更新事件的分发 Window的创建&#xff0c;更新&#xff1a; wi…

IT入门知识第二部分《编程语言》(2/10)

目录 IT入门知识博客文章大纲第二部分《编程语言》 1.引言 2.编程语言概述 2.1 编程语言的发展历程 2.2 编程范式 3.常见的编程语言 3.1 Python 3.2 Java 3.3 C 3.4 JavaScript 3.5 Ruby 4.编程语言的选择 4.1 技术需求 4.2 团队技能 4.3 社区和生态系统 4.4 可…

经验分享,CRC(循环冗余校验)在线计算

这里分享一个好用的在线计算CRC的网站。 网址&#xff1a;http://www.ip33.com/crc.html 截图&#xff1a;

Linux - 进程

一、什么是进程 首先&#xff0c;Linux是一个多用户多进程的操作系统&#xff0c;系统上可以同时运行多个进程。 进程的产生&#xff1a;①是在执行程序或者命令时产生的&#xff1b;②定时任务进程 进程的类型&#xff1a;前台进程/后台进程 前台进程&#xff1a;一个终端…

之所以选择天津工业大学,因为它是双一流、报考难度适宜,性价比高!天津工业大学计算机考研考情分析!

天津工业大学&#xff08;Tiangong University&#xff09;&#xff0c;简称“天工大”&#xff0c;位于天津市&#xff0c;是教育部与天津市共建高校、国家国防科技工业局和天津市共建的天津市重点建设高校、国家“双一流”建设高校、天津市高水平特色大学建设高校、中国研究生…

[Linux] 其他命令

cat cat是用法极多的一个命令&#xff1a; 1.输入输出 如果不加任何修饰&#xff0c;只一个cat&#xff0c;它是&#xff1a; 标准输入设备&#xff08;键盘&#xff09;——》标准输出设备&#xff08;显示器&#xff09; 显示文件内容&#xff1a; cat filename 输入重定向&a…

从0开始C++(二):类、对象、封装

目录 类&对象的概念 类的内容 对象的创建 ● 栈内存对象 ● 堆内存对象 封装 类&对象的概念 类和对象是一个比较抽象的概念&#xff0c;这里直接用一个实例方便理解。 类&#xff1a;类是一个抽象的概念&#xff0c;用来描述同一类对象的特点&#xff08;比如&am…

深圳中小企业融资攻略,贷款方法大盘点!

中小企业融资这事&#xff0c;可不是一个简单的事情。资金对中小企业来说&#xff0c;就像血液对人体一样重要。企业发展离不开资金支持&#xff0c;特别是在今年这个环境下&#xff0c;政策对中小企业还挺友好的。今天讲解一下中小微企业常用的几种贷款方法。希望能让大家更明…

Weaver E-Office v9.5 文件上传漏洞(CVE-2023-2648)

前言 CVE-2023-2648 是一个在 Weaver E-Office 9.5 版本中发现的严重漏洞。此漏洞位于文件 /inc/jquery/uploadify/uploadify.php 中&#xff0c;通过操控 Filedata 参数&#xff0c;可以进行不受限制的文件上传。这一漏洞允许攻击者上传可能包含危险类型的文件&#xff0c;并…

reason: the Java file contained parse errors

今天用Maven打包项目时发生一个错误&#xff1a; file: D:\workspace\echoo2.0-xxx-xxx-portal\src\main\java\com\echoo\service\impl\DecDataServiceImpl.java; reason: the Java file contained parse errors 打包报错显示这个类解析错误 在IDEA中没有任何错误提示 问题所…

​海康威视 isecure center 综合安防管理平台任意文件上传漏洞

文章目录 前言声明一、漏洞描述二、影响版本三、漏洞复现四、修复方案 前言 海康威视是以视频为核心的智能物联网解决方案和大数据服务提供商,业务聚焦于综合安防、大数据服务和智慧业务。 海康威视其产品包括摄像机、多屏控制器、交通产品、传输产品、存储产品、门禁产品、消…