java8新特性之--函数式接口加方法引用与构造器引用详细讲解

news2024/11/23 16:59:46

函数式(Functional)接口

什么是函数式(Functional)接口

只包含一个抽象方法的接口,称为函数式接口。

你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式 抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽 象方法上进行声明)。

我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检 查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个 接口是一个函数式接口。

在java.util.function包下定义了Java 8 的丰富的函数式接口
如下图所示

函数式接口举例

在这里插入图片描述

自定义函数式接口

注意接口名后面不要带括号
在这里插入图片描述

函数式接口中使用泛型:

在新特性中函数名后面可以指定泛型
在这里插入图片描述

作为参数传递 Lambda 表达式

在这里插入图片描述

为了将 Lambda 表达式作为参数传递,

接收Lambda 表达式的参数类型必须是与该 Lambda 表达式兼容的函数式接口的类型。

Java 内置四大核心函数式接口

在这里插入图片描述

代码示范

Predicate 断言型接口:

public class TestLambda3 {
	
	//Predicate<T> 断言型接口:
	@Test
	public void test4(){
		List<String> list = Arrays.asList("Hello", "atguigu", "Lambda", "www", "ok");
		List<String> strList = filterStr(list, (s) -> s.length() > 3);
		
		for (String str : strList) {
			System.out.println(str);
		}
	}
	
	//需求:将满足条件的字符串,放入集合中
	public List<String> filterStr(List<String> list, Predicate<String> pre){
		List<String> strList = new ArrayList<>();
		
		for (String str : list) {
			if(pre.test(str)){
				strList.add(str);
			}
		}
		
		return strList;
	}
}

Function<T, R> 函数型接口

public class TestLambda3 {
	//Function<T, R> 函数型接口:
	@Test
	public void test3(){
		String newStr = strHandler("\t\t\t 感谢大家观看", (str) -> str.trim());
		System.out.println(newStr);
		
		String subStr = strHandler("谢谢", (str) -> str.substring(2, 5));
		System.out.println(subStr);
	}
	
	//需求:用于处理字符串
	public String strHandler(String str, Function<String, String> fun){
		return fun.apply(str);
	}
}

Supplier 供给型接口

public class TestLambda3 {	
	//Supplier<T> 供给型接口 :
	@Test
	public void test2(){
		List<Integer> numList = getNumList(10, () -> (int)(Math.random() * 100));
		
		for (Integer num : numList) {
			System.out.println(num);
		}
	}
	
	//需求:产生指定个数的整数,并放入集合中
	public List<Integer> getNumList(int num, Supplier<Integer> sup){
		List<Integer> list = new ArrayList<>();
		
		for (int i = 0; i < num; i++) {
			Integer n = sup.get();
			list.add(n);
		}
		
		return list;
	}

Supplier 供给型接口

	//Consumer<T> 消费型接口 :
	@Test
	public void test1(){
		happy(10000, (m) -> System.out.println("大家好一瓶水:" + m + "元"));
	} 
	
	public void happy(double money, Consumer<Double> con){
		con.accept(money);
	}
}

其他接口

在这里插入图片描述

总结

何时使用lambda表达式?

当需要对一个函数式接口实例化的时候,可以使用 lambda 表达式。

何时使用给定的函数式接口?

如果我们开发中需要定义一个函数式接口,首先看看在已有的jdk提供的函数式接口是否提供了能满足需求的函数式接口。如果有,则直接调用即可,不需要自己再自定义了。
这样极大的帮助了程序员减轻了代码的繁杂

方法引用与构造器引用

当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!

方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。

要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的 方法的参数列表和返回值类型保持一致! 格式:使用操作符 “::” 将类(或对象) 与 方法名分隔开来。
如下三种主要使用情况:

  • 对象::实例方法名
  • 类::静态方法名
  • 类::实例方法名

使用要求

要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!(针对于1和2)

当函数式接口方法的第一个参数是需要引用方法的调用者,并且第二个参数是需要引用方法的参数(或无参数)时:ClassName::methodName(针对于3)

使用建议

如果给函数式接口提供实例,恰好满足方法引用的使用情境,就可以考虑使用方法引用给函数式接口提供实例。如果不熟悉方法引用,那么还可以使用 lambda 表达式。

方法引用代码示例

对象的引用 :: 实例方法名

//对象的引用 :: 实例方法名
	@Test
	public void test2(){
		Employee emp = new Employee(101, "张三", 18, 9999.99);
		
		Supplier<String> sup = () -> emp.getName();
		System.out.println(sup.get());
		
		System.out.println("----------------------------------");
		
		Supplier<String> sup2 = emp::getName;
		System.out.println(sup2.get());
	}

类名 :: 实例方法名

//类名 :: 实例方法名
	@Test
	public void test5(){
		BiPredicate<String, String> bp = (x, y) -> x.equals(y);
		System.out.println(bp.test("abcde", "abcde"));
		
		System.out.println("-----------------------------------------");
		
		BiPredicate<String, String> bp2 = String::equals;
		System.out.println(bp2.test("abc", "abc"));
		
		System.out.println("-----------------------------------------");
		
		
		Function<Employee, String> fun = (e) -> e.show();
		System.out.println(fun.apply(new Employee()));
		
		System.out.println("-----------------------------------------");
		
		Function<Employee, String> fun2 = Employee::show;
		System.out.println(fun2.apply(new Employee()));
		
	}
	

类名 :: 静态方法名

	//类名 :: 静态方法名
	@Test
	public void test4(){
		Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
		
		System.out.println("-------------------------------------");
		
		Comparator<Integer> com2 = Integer::compare;
	}
	
	@Test
	public void test3(){
		BiFunction<Double, Double, Double> fun = (x, y) -> Math.max(x, y);
		System.out.println(fun.apply(1.5, 22.2));
		
		System.out.println("--------------------------------------------------");
		
		BiFunction<Double, Double, Double> fun2 = Math::max;
		System.out.println(fun2.apply(1.2, 1.5));
	}

	

构造器引用

格式: ClassName::new

与函数式接口相结合,自动与函数式接口中方法兼容。 可以把构造器引用赋值给定义的方法,要求构造器参数列表要与接口中抽象 方法的参数列表一致!且方法的返回值即为构造器对应类的对象。

	@Test
	public void test7(){
		Function<String, Employee> fun = Employee::new;
		
		BiFunction<String, Integer, Employee> fun2 = Employee::new;
	}

数组引用

格式: type[] :: new

代码示范

//数组引用
	@Test
	public void test8(){
		Function<Integer, String[]> fun = (args) -> new String[args];
		String[] strs = fun.apply(10);
		System.out.println(strs.length);
		
		System.out.println("--------------------------");
		
		Function<Integer, Employee[]> fun2 = Employee[] :: new;
		Employee[] emps = fun2.apply(20);
		System.out.println(emps.length);
	}

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

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

相关文章

Java集合容器面试题

集合 什么是集合 集合就是用于存储数据的容器&#xff0c;只能存储引用类型&#xff0c;所以集合非常适合用来存储对象。而且集合是长度可变&#xff0c;所以对象个数不确定的时候适合使用集合 集合的特点 1、集合只能存储引用数据类型。集合用于存储对象。 2、对象的个数…

centos版本的EDA虚拟机搭建3

0、参考博客 1、CentOS 7 下 rar unrar的安装 1、配置虚拟机与主机共享文件夹。 **前提&#xff0c;虚拟机关机。**之后进行虚拟机设置&#xff0c;选项-共享文件夹&#xff0c;点击总是启用&#xff0c;之后添加共享文件夹名称。 之后打开虚拟机&#xff0c;命令行输入v…

【Leetcode60天带刷】day34贪心—— ​860. 柠檬水找零​,406.根据身高重建队列

​ 题目&#xff1a; 860. 柠檬水找零 在柠檬水摊上&#xff0c;每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品&#xff0c;&#xff08;按账单 bills 支付的顺序&#xff09;一次购买一杯。 每位顾客只买一杯柠檬水&#xff0c;然后向你付 5 美元、10 美元或 20 美元。…

Python零基础入门(五)——超详细的列表和元组介绍

系列文章目录 个人简介&#xff1a;机电专业在读研究生&#xff0c;CSDN内容合伙人&#xff0c;博主个人首页 Python入门专栏&#xff1a;《Python入门》欢迎阅读&#xff0c;一起进步&#xff01;&#x1f31f;&#x1f31f;&#x1f31f; 码字不易&#xff0c;如果觉得文章不…

Mysql 学习总结(88)—— Mysql 官方为什么不推荐用雪花 id 和 uuid 做 MySQL 主键

问题 在 MySQL 中设计表的时候,MySQL 官方推荐不要使用 uuid 或者不连续不重复的雪花 id(long 型且唯一),而是推荐连续自增的主键 id,官方的推荐是 auto_increment,那么为什么不建议采用 uuid,使用 uuid 究竟有什么坏处? MySQL 和程序实例 1、要说明这个问题,我们首先…

开关电源-6中常用的防反接电路

6种常用防反接电路介绍 电源反接&#xff0c;会给电路造成损坏&#xff0c;电源反接是不可避免的。所以我们就需要给电路中加入保护电路&#xff0c;达到即使接反电源&#xff0c;也不会损坏的目的&#xff0c;下面介绍几种常用防反接电路。 一、单二极管防反接电路 二极管防…

RabbitMQ 2023面试5题(一)

一、RabbitMQ延时队列可以用于哪些场景 RabbitMQ延时队列可以用于以下场景&#xff1a; 订单处理&#xff1a;在电商网站中&#xff0c;订单处理是一个常见的业务流程。如果订单需要立即处理&#xff0c;可以使用RabbitMQ的延时队列来实现延迟处理。例如&#xff0c;可以将订单…

SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接

文章目录 前后端对接前端接口修改对接后端后端总体配置后端编写登录登出业务代码 测试后端所有代码 前后端对接 前端接口修改对接后端 src\api\user.js中修改请求地址&#xff0c;与后端保持一致 记录下前端的src\utils\request.js中的X-Token字段 改变开发环境中的请求地…

Golang每日一练(leetDay0108) 灯泡开关I\II Bulb Switcher

目录 319. 灯泡开关 Bulb Switcher &#x1f31f;&#x1f31f; 672. 灯泡开关II Bulb Switcher ii &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每…

基于Java校园快递一站式服务系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

【八大排序(十)】八大排序效率与稳定性分析

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:八大排序专栏⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习排序知识   &#x1f51d;&#x1f51d; 八大排序总结 1. 前言2. 什么是排序算法的…

基于多模态变分对抗主动学习的下游医学图像分析任务

文章目录 M-VAAL: Multimodal Variational Adversarial Active Learning for Downstream Medical Image Analysis Tasks摘要本文方法实验结果 M-VAAL: Multimodal Variational Adversarial Active Learning for Downstream Medical Image Analysis Tasks 摘要 在医学领域&…

chatgpt赋能python:Python自动执行某个软件

Python自动执行某个软件 Python是一种简单易用且非常流行的编程语言&#xff0c;常用于自动化和数据分析。如果你想自动执行某个软件&#xff0c;那么Python将是一个非常好的选择。在本文中&#xff0c;我们将介绍如何使用Python自动执行某个软件&#xff0c;以及如何做好SEO优…

第 351 场LeetCode周赛

A 美丽下标对的数目 模拟 class Solution { public:int countBeautifulPairs(vector<int> &nums) {int n nums.size();int res 0;for (int i 0; i < n; i)for (int j i 1; j < n; j)if (gcd(to_string(nums[i])[0] - 0, to_string(nums[j]).back() - 0) …

人工智能技术与GIS结合的发展

个人本是GIS专业出身&#xff0c;不知名985高校本硕。工作几年后先后积累了国土空间规划、cesium开发、地理信息数据采集、地理大数据处理&#xff0c;遥感影像处理、人工智能识别&#xff0c;做过十多个500万以上的相关项目&#xff0c;有一些浅薄的经验&#xff0c;想和大家分…

tinykv project4总结

主要目标 实现mvcc和2pc, Percolator partA 将存储分为三个独立的部分&#xff0c;lock&#xff08;管理锁记录&#xff09; default(存储数据)&#xff0c;write(提交的记录)&#xff0c;提高并行性 对于lock存储&#xff0c;只要存储一份&#xff08;因为一个行同时只能有…

chatgpt赋能python:用Python编写聊天机器人:打造AI智能助手

用Python编写聊天机器人&#xff1a;打造AI智能助手 简介 聊天机器人在现代生活中越来越受欢迎。一个好的聊天机器人能够回答我们的问题、执行任务、提供娱乐&#xff0c;甚至成为我们的朋友。Python是一种强大的编程语言&#xff0c;其模块化和易学的特性使其成为开发聊天机…

GPT-4在药物发现中的作用|景联文科技

GPT-4是一种生成式AI模型&#xff0c;可以响应文本和图像&#xff0c;它代表了生成式AI可能实现的重大进步。 药物发现的最早任务之一是检索和观察与靶蛋白结合的已知分子。这可能会导致一种基于知识的筛选方法&#xff0c;人们试图通过仅检查这些分子来进行筛选。我们让GPT-4…

【MySQL数据库的表连接语句】

目录 一、连接查询1、inner join(内连接)2、left join(左连接)3、right join(右连接) 二、CREATE VIEW三、UNION取非交集的值 五、CASE六、空值(NULL) 和 无值() 的区别 一、连接查询 A表 B表 UPDATE store_info SET store_nameWashington WHERE sales300;#修改一下表里面的…

chatgpt赋能Python-python自动化办公真的有用吗_知乎

简介 如今&#xff0c;Python作为一种必学的编程语言&#xff0c;已经走进了各行各业的办公场景。Python自动化办公也逐渐成为了一个热门话题&#xff0c;很多人开始使用Python来进行一些机械化、重复性的办公工作&#xff0c;例如数据清洗、文本处理、文件管理、自动发送邮件…