PECS In Java泛型类型通配符限定之<? extends T>与<? super T>
泛型类型通配符限定 🚆
- PECS | 类型通配符限定
- 如何使用“<? extends T>”和“<? super T>”通配符
- java源码示例
PECS | 类型通配符限定
PECS原则是指在使用泛型时,当我们需要传递一个泛型集合时,如何选择适当的泛型类型通配符来限制集合中元素的类型。
这个原则有两个部分:
第一部分:“Producer Extends”,表示如果一个集合中的元素将被频繁读取而不是修改,那么我们应该使用限定类型通配符“<? extends T>”。这是因为如果我们使用非限定的类型参数 T,我们只能够保证集合中的元素是 T 类型,而不能保证它们的子类类型。但如果我们使用“<? extends T>”,我们可以确保集合中的元素类型是 T 或其子类,因此我们可以安全地从集合中读取元素并使用它们。
第二部分:“Consumer Super”,表示如果一个集合中的元素将被经常插入而不是读取,那么我们应该使用“<? super T>”通配符。这是因为使用非限定类型参数 T 时,我们只能保证集合中的元素类型是 T 或其父类类型,而不能保证它们是 T 类型或其子类类型。但如果我们使用“<? super T>”,我们可以安全地将类型为 T 或其子类类型的元素插入到集合中,因为这些元素都是 T 类型或其父类类型。
因此,PECS原则帮助我们选择适当的泛型类型通配符,以确保我们在使用泛型时能够正确地读取或修改集合中的元素,从而增强代码的可读性和可维护性。
如何使用“<? extends T>”和“<? super T>”通配符
假设我们有一个 Animal 类型和它的两个子类 Dog 和 Cat:
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
现在我们有一个方法,接受一个 Animal 类型的集合,并返回其中最后一个元素。我们可以这样实现该方法:
public static <T> T getLast(List<T> list) {if (list.isEmpty()) {return null;} else {return list.get(list.size() - 1);}
}
这个方法可以接受一个 Animal 类型的集合,但我们也可以使用限定类型通配符“<? extends T>”,来表示集合中的元素类型是 T 或其子类类型。这样我们就可以调用这个方法来获取一个元素类型为 Dog 或 Cat 的集合的最后一个元素:
List<Dog> dogs = Arrays.asList(new Dog(), new Dog());
Dog lastDog = getLast(dogs);List<Cat> cats = Arrays.asList(new Cat(), new Cat());
Cat lastCat = getLast(cats);
这里使用“<? extends T>”通配符,允许我们将 List 和 List 都传递给 getLast 方法,因为它们都是 Animal 类型的子类。
另一个示例是,假设我们有一个方法,接受一个 Animal 类型的集合和一个 Animal 类型的元素,将元素插入集合的最前面:
public static void insertFirst(List<? super Animal> list, Animal animal) {list.add(0, animal);
}
这个方法使用“<? super T>”通配符,表示集合中的元素类型是 T 或其父类类型。这样我们就可以调用这个方法来将一个类型为 Dog 或 Cat 的元素插入到一个类型为 Animal 的集合中:
List<Animal> animals = new ArrayList<>();
Dog dog = new Dog();
insertFirst(animals, dog);Cat cat = new Cat();
insertFirst(animals, cat);
这里使用“<? super Animal>”通配符,允许我们将 Animal、Dog、Cat 都插入到类型为 Animal 的集合中,因为它们都是 Animal 类型或其子类类型。
java源码示例
有一些 Java 标准库中的方法使用了“<? extends T>”和“<? super T>”通配符同时出现。一个经典的例子是 Collections.copy 方法,它将一个集合的内容复制到另一个集合中:
public static <T> void copy(List<? super T> dest, List<? extends T> src) {int srcSize = src.size();if (srcSize > dest.size()) {throw new IndexOutOfBoundsException("Source does not fit in dest");}for (int i = 0; i < srcSize; i++) {dest.set(i, src.get(i));}
}
在这个方法中,我们同时使用了“<? super T>”和“<? extends T>”通配符,因为我们需要同时支持将元素类型为 T 或其子类类型的源集合复制到元素类型为 T 或其父类类型的目标集合中。
通过使用“<? extends T>”通配符来限制源集合的元素类型,我们可以确保源集合中的元素类型是 T 或其子类类型。通过使用“<? super T>”通配符来限制目标集合的元素类型,我们可以确保目标集合中的元素类型是 T 或其父类类型。这样,即使源集合的元素类型是目标集合元素类型的子类,我们也可以安全地将源集合中的元素复制到目标集合中。
以下是使用 Collections.copy 方法的示例代码:
List<Animal> animals = new ArrayList<>(Arrays.asList(new Animal(), new Animal()));
List<Dog> dogs = Arrays.asList(new Dog(), new Dog());
Collections.copy(animals, dogs);
在这个示例中,我们将一个元素类型为 Dog 的集合复制到一个元素类型为 Animal 的集合中。由于我们在 copy 方法中使用了“<? super T>”和“<? extends T>”通配符,所以我们可以正确地将元素类型为 Dog 的集合复制到元素类型为 Animal 的集合中。
相关文章:
PECS In Java泛型类型通配符限定之<? extends T>与<? super T>
泛型类型通配符限定 🚆PECS | 类型通配符限定如何使用“<? extends T>”和“<? super T>”通配符java源码示例PECS | 类型通配符限定 PECS原则是指在使用泛型时,当我们需要传递一个泛型集合时,如何选择适当的泛型类型通配符来…...
电子招投标系统源码之了解电子招标投标全流程
随着各级政府部门的大力推进,以及国内互联网的建设,电子招投标已经逐渐成为国内主流的招标投标方式,但是依然有很多人对电子招投标的流程不够了解,在具体操作上存在困难。虽然各个交易平台的招标投标在线操作会略有不同࿰…...
admin Tips
1 获取 当前浏览器 url new URL(window.location.href)...
ToBeWritten之Radare2 使用教程
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...
实时翻译屏幕插件
程序插件的功能是:点击按钮,将获取屏幕截图,然后翻译输出图片。(目前只支持翻译英语) 要实现这个功能,我们可以使用Python编程语言,结合一些库来完成。以下是一个简单的实现方案: …...
代码随想录算法训练营第二天| 977,209,59
977.有序数组的平方 * 数组平方后,最大值一定是在两侧 因为可以采用双指针 package algor.trainingcamp;import java.util.Arrays;/*** author lizhe* version 1.0* description: https://leetcode.cn/problems/squares-of-a-sorted-array/** 有序数组的平方* 给…...
echarts 地图板块点击着色,移除着色
//选择省份变色 showProvince(name) { this.oldName name; this.mapChart && this.mapChart.dispatchAction({ type: geoSelect, name }) }, //移除上次点击变色 hideProvince() { this.mapChart && this.mapChart.dispatchAction({ type: geoUnSelect, name:…...
Visual Studio Code (vscode)自定义用户代码段快速打出for循环等
比如fori这样的快捷键就打不出代码块了 自定义用户代码块的方法: 工具栏 > 文件 > 首选项 > 用户代码片段 然后在弹出的搜索框中填写javascript.json 有提示 不用打全就行 (会有javascript选中) 打开配置文件javascript.json 这里面显示的就是编写代码块的例子 "…...
RocketMQ客户端配置详解
文章目录 ClientConfignamesrvAddrinstanceNameclientIPclientCallbackExecutorThreadspollNameServerIntervalheartbeatBrokerIntervalpersistConsumerOffsetIntervalvipChannelEnabledDefaultMQProducerproducerGroupcreateTopicKeydefaultTopicQueueNumssendMsgTimeoutcompr…...
STM32基于STM32CubeMX DMA + EXTI读取DS1307数据
STM32基于STM32CubeMX DMA EXTI读取DS1307数据✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创!🍁对于文中所提供的相关资源链接将作不定期更换。&a…...
C#中的枚举器和迭代器
目录 一、可枚举类型和枚举器 1. 枚举器 2. 可枚举类 3. 使用 IEnumerable 和 IEnumerator 案例 4. 泛型枚举接口 二、迭代器 1. 使用迭代器创建枚举器 2. 使用迭代器创建可枚举类 3. 常见的迭代器模式 4. 产生多个枚举类型 5. 将迭代器作为属性 6. 迭代器的实质 一…...
中山大学人工智能学院——考研上岸经验贴
文章目录初试个人基本情况408数学英语政治复试初试 首先是初试成绩,中山大学在2.21号就公布了成绩和排名,这点很不错,有很多学校只公布成绩而没有排名。我的初试总分386,总排名第二,各个科目还是比较平均的࿱…...
ThreeJS-圣诞节表白3D贺卡(三十)
素材分享: 链接: https://pan.baidu.com/s/1l0mZWfkiLaXJfdvZ7XoY8w 提取码: i69h 提前预知: 向下滚动鼠标滑轮切换视角 关键代码: //初始化渲染器 const render new THREE.WebGLRenderer({ //设置抗锯齿,防失真 antialis: …...
040:cesium加载World Terrain地形图
第040个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中加载世界地形图。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共64行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:https://xiaozh…...
逻辑运算和位移指令
逻辑运算指令 AND OR NOT XOR TEST 逻辑位移指令 SHL SHR 算术位移指令 SAL SAR 小循环位移指令 ROL ROR 大循环位移指令 RCL RCR AND 逻辑与指令 汇编格式:AND 目的操作数,源操作数 执行操作:(目的操作数)&…...
大家现在都去做Linux运维了吗?
运维自互联网出现以来,都是以基础技术部门的形式出现在各个互联网公司或者其他需要网络设备的公司里面,职位由来已久,也是多次徘徊在被淘汰的边缘。很多运维人都是靠着自己良好乐观的心态坚持到现在,接受新技术并学习新技术&#…...
Webpack的编译流程是怎么样的?webpack是如何工作的?
Webpack是一款非常流行的前端构建工具,用于将多个模块打包成一个或多个静态资源。它的工作原理是将模块的依赖关系图转化为最终的静态资源。Webpack的编译流程是一个非常复杂的过程,本文将从四个方面详细介绍Webpack的编译流程,分别是入口点分…...
【ZOJ 1151】Word Reversal 题解(字符串+模拟)
问题描述 对于每个单词列表,在不改变单词顺序的情况下,将每个单词反转输出一行。 此问题包含多个测试用例! 多重输入的第一行是整数N,然后是空行,后面跟着N个输入块。每个输入块 采用问题描述中所示的格式。输入块之间…...
Dart语言操作符?和!的用法
一.基本使用 1. ? 操作符跟在类型后面,表示当前变量可为null。 int a null; //这句代码在有空安全时,编译会提示错误如果想给一个变量赋值null要如何处理呢?只需要在类型 后面添加操作符?即可,eg: int? a null…...
聚类 kmeans | 机器学习
聚类 刘建平 1、算法原理: 是一种无监督学习算法,其主要目的是将数据点分为k个簇,距离近的样本具有更高的相似度,距离近的划分为一个簇,一共划分k个簇,**让簇内距离小,簇间距离大。**距离是样…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...
RFID推动新能源汽车零部件生产系统管理应用案例
RFID推动新能源汽车零部件生产系统管理应用案例 一、项目背景 新能源汽车零部件场景 在新能源汽车零部件生产领域,电子冷却水泵等关键部件的装配溯源需求日益增长。传统 RFID 溯源方案采用 “网关 RFID 读写头” 模式,存在单点位单独头溯源、网关布线…...
盲盒一番赏小程序:引领盲盒新潮流
在盲盒市场日益火爆的今天,如何才能在众多盲盒产品中脱颖而出?盲盒一番赏小程序给出了答案,它以创新的玩法和优质的服务,引领着盲盒新潮流。 一番赏小程序的最大特色在于其独特的赏品分级制度。赏品分为多个等级,从普…...
【SSM】SpringMVC学习笔记7:前后端数据传输协议和异常处理
这篇学习笔记是Spring系列笔记的第7篇,该笔记是笔者在学习黑马程序员SSM框架教程课程期间的笔记,供自己和他人参考。 Spring学习笔记目录 笔记1:【SSM】Spring基础: IoC配置学习笔记-CSDN博客 对应黑马课程P1~P20的内容。 笔记2…...
