当前位置: 首页 > news >正文

Java设计模式之适配器模式:深入JDK源码探秘Set类

在Java编程中,Set类作为一个不允许存储重复元素的集合,广泛应用于数据去重、集合运算等场景。然而,你是否曾好奇Set类是如何在底层实现元素唯一性判断的?这背后隐藏的力量正是适配器模式。

适配器模式简介

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端期望的另一个接口,从而使原本不兼容的类可以一起工作。适配器模式的核心思想是通过适配器类来转换接口,使得原本由于接口不兼容而不能一起工作的类能够协同工作。

在适配器模式中,通常包含三个角色:

  1. Target(目标接口):定义客户端所期待的接口。
  2. Adaptee(适配者):已经存在的类,需要适配的类,它提供了一些有用的方法,但接口不符合客户端的要求。
  3. Adapter(适配器):适配器类,它实现了目标接口,并将请求转发给适配者类。
Set类中的适配器模式应用

在JDK源码中,Set类的实现巧妙地运用了适配器模式。具体来说,HashSet、LinkedHashSet和TreeSet这三个主要的Set实现类,都通过适配器模式实现了各自的功能。

  1. HashSet

HashSet内部持有一个transient的HashMap实例,通过HashMap的键的唯一性来保证Set中元素的唯一性。当我们调用HashSet的add方法时,实际上是将元素作为HashMap的键,而一个固定的PRESENT对象作为值,存入了HashMap中。这样一来,通过HashMap键的唯一性,就轻松保证了Set中元素的唯一性。

 

java复制代码

private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT) == null;
}

获取HashSet的迭代器时,它直接返回的是HashMap的键集合的迭代器,这使得我们在遍历HashSet时,实际上是在遍历HashMap的键,从而获取到Set中的所有元素。

 

java复制代码

public Iterator<E> iterator() {
return map.keySet().iterator();
}
  1. LinkedHashSet

LinkedHashSet在构造函数中调用了父类的构造函数,最终创建了一个LinkedHashMap。LinkedHashSet利用LinkedHashMap的有序特性,不仅实现了元素的唯一性,还能保持元素插入的顺序,为我们提供了一种有序的Set实现。

 

java复制代码

public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}

其构造函数最终会调用到类似这样的父类构造函数,创建一个LinkedHashMap实例。

 

java复制代码

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
  1. TreeSet

TreeSet内部持有一个transient的NavigableMap实例,通过将元素存储在NavigableMap中,并利用其排序功能,实现了对元素的有序存储和操作,为我们提供了一个有序且不重复的Set集合。

 

java复制代码

private transient NavigableMap<E,Object> m;
private static final Object PRESENT = new Object();
适配器模式的优势

通过适配器模式,Set类实现了与不同底层数据结构(如HashMap、LinkedHashMap和TreeMap)的无缝对接,从而提供了高效且灵活的集合操作。适配器模式的优势主要体现在以下几个方面:

  1. 提高了类的复用性:通过适配器模式,我们可以将已有的类进行复用,而无需修改其结构。
  2. 提高了系统的灵活性和可扩展性:当需要引入一个新的接口时,只需增加一个新的适配器类,而无需修改原有代码。
  3. 降低了系统间的耦合度:通过适配器模式,我们可以将原本紧密耦合的两个系统解耦,从而提高系统的可维护性和稳定性。
总结

通过深入剖析JDK源码中Set类对适配器模式的应用,我们不仅揭开了Set类高效实现元素唯一性判断和操作的神秘面纱,更深刻体会到了设计模式在优化代码结构、提高代码复用性和灵活性方面的巨大威力。在日常编程中,我们应深入源码,学习大师们的设计思路和技巧,不断提升自己的编程水平,打造出更加高效、健壮、优雅的软件系统。

相关文章:

Java设计模式之适配器模式:深入JDK源码探秘Set类

在Java编程中&#xff0c;Set类作为一个不允许存储重复元素的集合&#xff0c;广泛应用于数据去重、集合运算等场景。然而&#xff0c;你是否曾好奇Set类是如何在底层实现元素唯一性判断的&#xff1f;这背后隐藏的力量正是适配器模式。 适配器模式简介 适配器模式&#xff0…...

java八股-流量封控系统

文章目录 请求后台管理的频率-流量限制流量限制的业务代码UserFlowRiskControlFilter 短链接中台的流量限制CustomBlockHandler 对指定接口限流UserFlowRiskControlConfigurationSentinelRuleConfig 请求后台管理的频率-流量限制 根据登录用户做出控制&#xff0c;比如 x 秒请…...

【WebRTC】Android SDK使用教学

文章目录 前言PeerConnectionFactoryPeerConnection 前言 最近在学习WebRTC的时候&#xff0c;发现只有JavaScript的API文档&#xff0c;找了很久没有找到Android相关的API文档&#xff0c;所以通过此片文章记录下在Android应用层如何使用WebRTC 本篇文章结合&#xff1a;【W…...

基于单片机的智能晾衣控制系统的设计与实现

摘要:本文是以 AT89C52 单片机为核心来实现智能晾衣控制系统。在这个系统中,雨水检测传感器是用来检测出雨的,而控制器将检测信号的变换,根据变换后的信号自动驱动直流电机将被风干 的棒收回,以便随时控制直流电机来实现晾衣;在光敏模块中检测昼夜的环境,自动控制晾衣杆…...

多人聊天室 NIO模型实现

NIO编程模型 Selector监听客户端不同的zhuangtai不同客户端触发不同的状态后&#xff0c;交由相应的handles处理Selector和对应的处理handles都是在同一线程上实现的 I/O多路复用 在Java中&#xff0c;I/O多路复用是一种技术&#xff0c;它允许单个线程处理多个输入/输出&…...

三、使用 Maven:命令行环境

文章目录 1. 第一节 实验一&#xff1a;根据坐标创建 Maven 工程1.1 Maven 核心概念&#xff1a;坐标1.2 实验操作1.3 Maven核心概念&#xff1a;POM1.4 Maven核心概念&#xff1a;约定的目录结构 2. 实验二&#xff1a;在 Maven 工程中编写代码2.1 主体程序2.2 测试程序 3. 执…...

Blender导入下载好的fbx模型像的骨骼像针戳/像刺猬

为什么我下载下来的骨骼模型和我自己绑定的模型骨骼朝向完全不一样 左边是下载的模型 右边是我自己绑定的模型 左边的模型刚刚感觉都是像针一样往外戳的&#xff0c;像刺猬一样那种。 解决方法勾选自动骨骼坐标系...

如何高效搭建智能BI数据分析系统

作为当今信息化时代&#xff0c;数据资产已经成为企业最为核心倚重的&#xff0c;自然企业也就面临来自于对内部这些数据的处理和分析。如何在大批量的数据当中提取有用信息&#xff0c;帮助企业做出智慧决策&#xff0c;是不少企业面临的问题。作为国内知名的BI数据分析系统服…...

第 6 章 Java 并发包中锁原理剖析Part one

目录 6.1 LockSupport 工具类 6.2 独占锁 ReentrantLock 的原理 获取锁 1&#xff0e;void lock() 方法 2&#xff0e;void lockInterruptibly() 方法 3&#xff0e;boolean tryLock() 方法 4&#xff0e;boolean tryLock(long timeout, TimeUnit unit) 方法 释放锁 6.1 Lo…...

使用 Canvas 绘制一个镂空的圆形区域

如果要实现一个类似人脸识别的界面&#xff0c;要求使用 canvas 进行绘制&#xff0c;中间镂空透明区域&#xff0c;背景是白色的画布。 技术方案&#xff1a; 首先&#xff0c;使用 canvas 绘制一个白色画布其次&#xff0c;使用 context.globalCompositeOperation 合成属性进…...

【Notepad++】---设置背景为护眼色(豆沙绿)最新最详细

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【Notepad】---设置背景为护眼色&#xf…...

2024 数学建模国一经验分享

2024 数学建模国一经验分享 背景&#xff1a;武汉某211&#xff0c;专业&#xff1a;计算机科学 心血来潮&#xff0c;就从学习和组队两个方面指点下后来者&#xff0c;帮新人避坑吧 2024年我在数学建模比赛中获得了国一&#xff08;教练说论文的分数是湖北省B组第一&#xff0…...

安全见闻2

安全见闻&#xff0c;犹如一座庞大而深邃的知识宝库&#xff0c;其中涵盖了形形色色的网络安全知识与错综复杂的网络技术体系。在当今数字化时代&#xff0c;这些领域的重要性不言而喻&#xff0c;它们不仅关乎个人信息的保护与隐私安全&#xff0c;更是支撑着整个互联网世界以…...

Web游戏开发指南:在 Phaser.js 中读取和管理游戏手柄输入

前言 Phaser.js 是一个广受欢迎的 HTML5 游戏框架&#xff0c;为开发者提供了创建跨平台 2D 游戏的强大工具。在现代游戏开发中&#xff0c;支持游戏手柄已成为提升玩家体验的重要方面。本文将详细介绍如何在 Phaser.js 中监听和处理游戏手柄的输入&#xff0c;帮助开发者为他…...

代码随想录32 动态规划理论基础,509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯。

1.动态规划理论基础 动态规划刷题大纲 什么是动态规划 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的…...

记录一个Flutter 3.24单元测试点击事件bug

哈喽&#xff0c;我是老刘 这两天发现一个Flutter 3.24版本的单元测试的一个小bug&#xff0c;提醒大家注意一下。 老刘自己写代码十多年了&#xff0c;写Flutter也6年多了&#xff0c;没想到前两天在一个小小的BottomNavigationBar 组件上翻了车。 给大家分享一下事件的经过。…...

使用Python将 word文档转pdf文档

第一步&#xff1a;我们需要导入支持包 >pip install pywin32 如果下载速度比较慢的话&#xff0c;可以考虑使用国内镜像源。 第二步&#xff1a;我们需要导入文件&#xff0c;这里采用 input,用户填入路径后&#xff0c;直接获取路径下的word文档&#xff0c;实现批量转换…...

基于C#+SQLite开发数据库应用的示例

SQLite数据库&#xff0c;小巧但功能强大&#xff1b;并且是基于文件型的数据库&#xff0c;驱动库就是一个dll文件&#xff0c;有些开发工具 甚至不需要带这个dll&#xff0c;比如用Delphi开发&#xff0c;用一些三方组件&#xff1b;数据库也是一个文件&#xff0c;虽然是个文…...

Vue基本语法

Options API 选项式/配置式api 需要在script中的export default一个对象对象中可以包含data、method、components等keydata是数据&#xff0c;数据必须是一个方法&#xff08;如果是对象&#xff0c;会导致多组件的时候&#xff0c;数据互相影响&#xff0c;因为对象赋值后&…...

芯片发展史

芯片的发展史可分为几个重要的阶段&#xff0c;从早期的真空管到现代的集成电路&#xff0c;反映了技术进步和创新的历程&#xff1a; 1. 真空管时代 (1904 - 1950年代) 真空管是20世纪初的电子元件&#xff0c;用于放大信号和开关&#xff0c;广泛应用在早期的收音机、电视机…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...