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

在编程中,方法引用(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>() {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic 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.mzph.cn/news/856001.shtml

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

相关文章

业务谈判的过程中多让客户做选择

之前还在工厂的时候&#xff0c;开分享会&#xff0c;经理会反复强调的一个跟进思路就是一定要学会让客户跟着我们的节奏走&#xff0c;而不是被客户牵着鼻子走。 前者会让客户顺着我们设计好的谈判路径&#xff0c;把客户引导到我们想要的结果上&#xff0c;业务员是主动角色…

嵌入式系统软件开发环境_1.定义及特点和分类

1.嵌入式系统软件开发环境的定义及特点 嵌入式系统软件开发环境是可帮助用户开发嵌入式软件的一组工具的集合&#xff0c;这种工具的集合被集成为一体&#xff0c;形成一套交叉平台开发方法&#xff08;Cross Platform Development&#xff0c;CPD&#xff09;。交叉开发方法是…

模版与策略模式

一&#xff0c;怎么选择 如果需要固定的执行流程&#xff0c;选模版 如果不需要固定的执行流程&#xff0c;只需要对一个方法做具体抽象&#xff0c;选策略 参考文章&#xff1a; 常用设计模式汇总&#xff0c;告诉你如何学习设计模式 二&#xff0c;常用写法 子类 exten…

【Android面试八股文】Kotlin协程在工作中有用过吗?

文章目录 1.你工作这么些年,对于Kotlin语言协程是什么,有了解么?2.那这样说的话,协程到底有什么用?2.2.1 多个请求并发和合并的问题2.2.2 会引发嵌套回调地狱问题2.2.3 Rx解决回调地狱2.2.4 协程来解决此问题2.2.5 协程是什么?总结扩展阅读1.你工作这么些年,对于Kotlin语…

穿越时空的家书——黑夫与惊的不朽传奇

1975年&#xff0c;湖北云梦县睡虎地的一次考古发掘&#xff0c;揭开了一段尘封的历史&#xff0c;两枚刻有527个字的木牍&#xff0c;成为了我国最早的家书实物。这两枚木牍&#xff0c;记录了战国时期秦国士兵黑夫和惊的家书。 两件木犊出土时被放置在墓地陪葬器物箱子里的中…

【学习笔记】Hausdorff 距离的 C 语言实现

Hausdorff 距离的 C 语言实现 简介 Hausdorff 距离&#xff0c;亦称为豪斯多夫距离&#xff0c;是由德国数学家费利克斯豪斯多夫&#xff08;Felix Hausdorff&#xff09;提出的一种度量空间中两个非空集合之间远近程度的方法。这种距离度量广泛应用于计算机视觉、图像处理、…

Nuxt3 实战 (十):使用 Supabase 实现 RESTful 风格 API 接口

前言 本篇文章我们来使用 Supabase 实现 RESTful 风格的 API 接口&#xff0c;以此来实现网站分类和子站点的 CURD 功能。 表设计 这里需要用到两张表&#xff1a; ds_categorys&#xff1a;存储网站分类 列名类型备注iduuid主键&#xff0c;分类 idnametext分类名称desct…

python 魔术方法备忘录

python 魔术方法备忘录 网上收集了一些&#xff0c;列出了比较常用的&#xff0c;特别是第一张。 Python中的魔术方法&#xff08;Magic Methods&#xff09;&#xff0c;也被称为特殊方法&#xff08;Special Methods&#xff09;或双下划线方法&#xff08;Dunder Methods&a…

Python2 日志模块的使用

Python中的日志模块&#xff08;logging module&#xff09;提供了灵活的日志记录功能&#xff0c;使开发者能够在程序运行时记录各种级别的信息&#xff0c;从而方便调试、跟踪程序的执行情况&#xff0c;并定位可能出现的问题。 日志模块可以用来&#xff1a; 记录程序的运行…

Effective C++ 改善程序与设计的55个具体做法笔记与心得 2

二. 构造/析构/赋值运算 5. 了解C默默编写并调用哪些函数 唯有当这些函数被调用&#xff0c;他们才会被编译器创建出来。 请记住&#xff1a; ‌‌‌‌  编译器可以暗自为class创建default构造函数、copy构造函数、copy assignment操作符&#xff0c;以及析构函数。 6. 若…

渗透测试之存储型跨站脚本攻击(高危)

一、定义 跨站脚本攻击&#xff0c;指的是恶意用户往web页面里插入恶意HTML代码。当普通用户访问该web页面&#xff0c;嵌入其中的HTML代码会被执行&#xff0c;从而达到破坏的效果。 二、风险定级 高危 三、可输入的HTML标签示例 图片标签 <img src"#"> 超…

有监督学习——决策树、集成学习

1. 决策树 熵 在热力学中&#xff0c;熵&#xff08;entropy&#xff09;被用来衡量系统的不稳定程度。香农在论文《通信的数学原理》中提出信息熵的概念&#xff0c;目的是_量化数字信息的价值_。 信息熵的定义 香农提出的量化信息方式&#xff1a; \[H(P_1,P_2,\cdots P…

新建一个 React TypeScript 项目,并使用 Webpack 进行构建和打包

要用 create-react-app 新建一个 React TypeScript 项目&#xff0c;并使用 Webpack 进行构建和打包&#xff0c;可以按照以下步骤进行操作&#xff1a; 步骤 1&#xff1a;使用 create-react-app 创建 React TypeScript 项目 确保你已经安装了 Node.js 和 npm&#xff08;Nod…

【代码随想录算法训练Day43】LeetCode 518.零钱兑换II、LeetCode 377.组合总和IV、LeetCode 70.爬楼梯

Day43 动态规划第五天 LeetCode 518.零钱兑换II dp数组的含义&#xff1a;装满容量为j的背包有dp[j]种方法 递推公式&#xff1a;dp[j]dp[j-coins[i]]。 初始化&#xff1a;dp[0]1,dp[j]0 遍历顺序&#xff1a;先物品后背包&#xff0c;背包内从小到大 本题是组合数&#xff…

【Android面试八股文】你能讲一讲Kotlin语言泛型的形变是什么?

文章目录 1. 协变 (`out`)1.1 协变概念1.2 协变示例1.3 为什么协变只能读取泛型,而不能修改泛型?1. 原因概述2. 类型安全性问题3. 类型一致性结论2. 逆变 (`in`)2.1 逆变概念2.2 逆变示例2.3 为什么逆变只能修改泛型,不能读取泛型?2.3.1 为什么逆变只能读取泛型,不能修改泛…

吴恩达机器学习作业ex3:多类分类和前馈神经网络(Python实现)详细注释

文章目录 1 多类分类1.1数据集1.2 数据可视化1.3 向量化逻辑回归1.3.1 向量化代价函数1.3.2 矢量化梯度下降以及正则化表达1.4 一对多分类 2.神经网络2.1模型表示 总结&#xff08;自己训练求解参数全流程&#xff09; 1 多类分类 在本练习中&#xff0c;您将使用逻辑回归和神…

Redis学习|Jedis、SpringBoot整合Redis

Jedis 我们要使用Java 来操作 Redis,知其然并知其所以然&#xff0c;授人以渔!学习不能急躁&#xff0c;慢慢来会很快!什么是Jedis 是 Redis 官方推荐的java连接开发工具!使用java 操作Redis 中间件!如果你要使用 java操作redis&#xff0c;那么一定要对Jedis 十分的熟悉! 1、…

MySQL之复制(五)

复制 复制的原理 复制文件 3.master.info 这个文件用于保存备库连接到主库所需要的信息&#xff0c;格式为纯文本(每行一个值)&#xff0c;不同的MySQL版本&#xff0c;其记录的信息也可能不同。此文件不能删除&#xff0c;否则备库在重启后无法连接到主库。这个文件以文本的…

电脑ffmpeg.dll丢失原因解析,找不到ffmpeg.dll的5种解决方法

在数字化时代&#xff0c;多媒体文件的处理已经成为我们日常生活和工作中不可或缺的一部分。在计算机使用过程中&#xff0c;丢失ffmpeg.dll文件是一个特定但常见的问题&#xff0c;尤其是对于那些经常处理视频编解码任务的用户来说。下面小编讲全面分析ffmpeg.dll丢失原因以及…

android webview调用js滚动到指定位置

一、activity import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.tencent.smtt.sdk.WebView import com.tencent.smtt.sdk.WebViewClientclass MainActivity : AppCompatActivity() {private lateinit var webView: WebViewoverride fun …