HashSet 、LinkedHashSet 源码级详解

Set 集合类体系如下:

HashSet -- 无序、不重复、无索引

LinkedHashSet -- 有序、不重复、无索引

TreeSet -- 可排序、不重复、无索引

HashSet

HashSet 底层采用 哈希表 存储数据

哈希表组成

JDK8 之前  -- 数组 + 链表

JDK8 之后  -- 数组 + 链表 +红黑树

一开始会把元素存储在数组中,但是哈希表会出现同一个索引位置要存储多个元素的情况,因此要将同一个索引位置的多个对象用链表或红黑树进行存储

哈希表的核心 -- 哈希值

哈希值我们可以理解为对象的整数形式

因为在哈希表存储的时候,不是从索引零开始按序存储的,而是根据公式

int index = (数组长度 - 1 )& 哈希值

index就是对象存储的位置

对象可以根据 hashCode 方法计算出哈希值,该方法定义在Object类中,因此所有对象都可调用,默认使用地址值进行计算,但是一般情况下用对象的地址值计算哈希值的意义不大,因此一般情况下会重写 hashCode 方法,利用对象内部属性计算哈希值

关于 hashCode 方法 重写,最重要的是 hashCode 方法和 equals 方法的联系,可以参考以下博客

(8条消息) 为什么重写 equals 方法就必须重写 hashCode 方法?_Fearless____的博客-CSDN博客https://blog.csdn.net/Fearless____/article/details/131786820

我们对 对象相等 的定义是:当两个对象 equals 返回 true 时,则两个对象就是相同的

但是当两个对象不相等时,可能会得到相同的哈希值

哈希表存储的原理:

  • 通过哈希值计算出存储的位置,如果该位置为null,则直接存入;
  • 如果不为null,则调用equals方法(不为null说明多个对象的哈希值相等,但是哈希值相等不代表元素相等,元素是否相等的标准由equals判断),如果该位置存在equals为true的元素,则不存储,如果没有则存储(以链表或红黑树的形式存储)

所以从上面看出,哈希值具有两个作用,一是计算出存储位置,二是初步判断哈希表中是否存在相同元素

正是因为哈希表具有不存储相同对象的特点,HashSet才能做到不重复

又因为哈希表是数组+链表+红黑树,并且不是从索引0开始按序存储,所以HashSet是无序的、无索引的

如下图,在遍历的时候,会先查看0索引位置,没有元素,那么查看1索引位置,遍历该链表,继续查看2索引位置... 以此类推,因此遍历的结果是 黄 -> 橙 -> .. -> 深蓝 -> 浅蓝 ,而我们存储的顺序可能是 橙 -> 浅蓝 -> ... -> 蓝->黄

LinkedHashSet

本质上跟 HashSet 相同,只不过多了个双链表的机制记录储存的顺序

现在我们要将这四个元素存入哈希表中

 现在存入第一个元素,此时还有一条双向链表,双向链表的头结点指向该元素

存入第二个元素,此时,第一个元素会记录下第二个元素的地址值,第二个元素也会记录第一个元素的地址值,这就形成了一个双向链表

存入第三个元素,第三个元素和第四个元素间同样会相互记录地址值

 存入第四个元素

接下来要遍历的时候,不再和HashSet相同,而是直接从头节点开始遍历该双向链表,最后得到的结果就是有序的

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

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

相关文章

OpenVas扫描器更新扫描引擎

OPenvas扫描器安装时step1 是交换指导升级(nvt,cert,scap),这次升级后是自动升级24h升级一次,但第一次升级时选择默认的rsync升级时会出现同步失败的问题,导致openvas安装完后有很大模块和规则不…

字符设备驱动开发(最初方式)

目录: 1.字符设备驱动简介2.字符设备驱动开发步骤2.1. 驱动模块的加载与卸载2.2. Makefile的编写2.3.字符设备的注册与注销2.3.1.设备号的组成2.3.2.设备号的分配 2.4.具体操作函数的实现2.4.1.进行打开和关闭操作2.4.2.对chrdev进行读写操作 3.具体程序的实现3.1.驱…

MySql如何卸载干净经验分享

第一步:首先打开注册表:点击电脑的开始按钮,打开找到运行,输入regedit,进入注册表; 第二步:删除mysql再注册表中的信息,以下三个目录: 1.HKEY_LOCAL_MACHINE\SYSTEM\Cont…

计讯物联5G千兆网关TG463在电力智能巡检机器人的应用功能解析

项目背景 随着国家智能电网建设加速推进,投资规模持续扩大,我国电网智能化、信息化不断提高,传统的电力运维与管理模式早已不能满足智能电网快速发展的需求。因此,在5G无线通信、人工智能、物联网、云计算、大数据、电力等前沿技术…

现货白银投资技巧有哪些

突破交易策略,适用于现货银价建立调整平台后,走势突然向上或向下运行的情况。所谓平台,就是是像箱子一样的矩形形态,即银价在两条水平直线之间上下波动,既上不去也下不来,一直在矩形内横向整理。这种形态通…

TCP 协议(五)异常报文

TCP 协议(一)报文结构 TCP 协议(二)连接与断开 TCP 协议(三)十种核心机制 TCP 协议(四)重传与超时 TCP 协议(五)异常报文 1.[TCP Dup ACK xxx#y]&#xff08…

关于Qt编译android时候一个问题

问题提示为 FAILURE: Build failed with an exception.* What went wrong: A problem occurred configuring root project android-build. > Could not resolve all artifacts for configuration :classpath.> Could not resolve com.android.tools.build:gradle:3.2.0.…

kafka消息队列最常用的两种模式,以及应用场景

目录 一、发布-订阅模式 二、点对点模式 三、应用场景 一、发布-订阅模式 发布-订阅模式是最常见的消息传递模式,其中消息发布者将消息发送到一个或多个主题(Topic),而订阅者可以选择订阅一个或多个主题来接收消息。每个订阅者…

深入理解网络栈

网络路径 发送端 应用层 1、socket 各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的 socket 是网络编程的入口,它提供了大量的系统调用,构成了网络程序的主体 udp UDP 是面向无连接的协议,不需要与…

Linux的权限管理精细总结

(该图由AI绘制 关注我 学习AI画图) 目录 一、权限概述 1、权限的基本概念 2、为什么要设置权限 3、Linux用户身份类别 4、user文件拥有者 5、group文件所属组内用户 6、other其他用户 7、特殊用户root 二、普通权限管理 1、ls -l命令查看文件…

项目名称:无源在线词典项目

一,概述 基于C语言的网络电子词典项目,使用到了tcp协议的并发服务器设计、网络编程、文件I/O、数据库等多方面的知识。可以满足多用户同时登陆,用户登陆后可以查询单词及历史记录,具有查找快速,保密性好等优点。 开…

详细介绍MATLAB中的图论算法

MATLAB是一种功能强大的编程语言和环境,提供了许多用于图论算法的工具和函数。图论是研究图及其属性和关系的数学分支,广泛应用于计算机科学、网络分析、社交网络分析等领域。在MATLAB中,我们可以使用图论算法来解决各种问题,如最短路径问题、最小生成树问题、最大流问题等…