【Java基础知识总结 | 第十篇】HashSet底层实现原理

在这里插入图片描述

文章目录

  • 10.HashSet底层实现原理
    • 10.1HashSet特点
    • 10.2HashSet源码
    • 10.3 add流程
    • 10.4总结

10.HashSet底层实现原理

10.1HashSet特点

  1. 存储对象:HashSet 存储对象采用哈希表的方式,它不允许重复元素,即集合中不会包含相同的元素。当向 HashSet 中添加元素时,会根据元素的 hashCode() 方法和 equals() 方法来判断元素是否重复。
  2. 底层数据结构:HashSet 的底层数据结构是基于 HashMap 实现的,实际上 HashSet 的元素就是作为 HashMap 的 key 存储的。
  3. null 值问题:HashSet 允许存储一个 null 元素。
  4. 线程安全问题:不安全

10.2HashSet源码

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable{  
    
 	// 使用 HashMap 的 key 保存 HashSet 中所有元素  
 	private transient HashMap<E,Object> map;   
    
 	// 定义一个虚拟的 Object 对象作为 HashMap 的 value   
 	private static final Object PRESENT = new Object();// 构造方法,初始化 HashSet,底层会初始化一个 HashMap   
 	public HashSet(){   
    	map = new HashMap<E,Object>();   
 	}   
    
 	// 以指定的 initialCapacity、loadFactor 创建 HashSet   
 	// 其实就是以相应的参数创建 HashMap   
 	public HashSet(int initialCapacity, float loadFactor){   
    	map = new HashMap<E,Object>(initialCapacity, loadFactor);   
 	}   
 	
    public HashSet(int initialCapacity){   
    	map = new HashMap<E,Object>(initialCapacity);   
	}   
 	
    HashSet(int initialCapacity, float loadFactor, boolean dummy){   
    	map = new LinkedHashMap<E,Object>(initialCapacity   
         , loadFactor);   
 	}   
 	
    // 调用 map 的 keySet 来返回所有的 key   
 	public Iterator<E> iterator(){   
    	return map.keySet().iterator();   
 	}   
 	
    // 调用 HashMap 的 size() 方法返回 Entry 的数量,就得到该 Set 里元素的个数  
 	public int size(){   
    	return map.size();   
 	}  
    
 	// 调用 HashMap 的 isEmpty() 判断该 HashSet 是否为空,  
 	// 当 HashMap 为空时,对应的 HashSet 也为空  
 	public boolean isEmpty(){   
     return map.isEmpty();   
 	}   
 
    // 调用 HashMap 的 containsKey 判断是否包含指定 key   
	//HashSet 的所有元素就是通过 HashMap 的 key 来保存的  
	public boolean contains(Object o){   
    	return map.containsKey(o);   
	}   
 
    // 将指定元素放入 HashSet 中,也就是将该元素作为 key 放入 HashMap   
	public boolean add(E e){   
 	   return map.put(e, PRESENT) == null;   
	}   
 
    // 调用 HashMap 的 remove 方法删除指定 Entry,也就删除了 HashSet 中对应的元素  
 	public boolean remove(Object o){   
    	return map.remove(o)==PRESENT;   
	}   
 
    // 调用 Map 的 clear 方法清空所有 Entry,也就清空了 HashSet 中所有元素  
 	public void clear(){   
    	map.clear();   
 	}} 

10.3 add流程

  1. HashSet底层使用了哈希表来支持的,特点:存储快;
  2. 往Haset添加元素的时候,HashSet会先调用元素的hashCode方法得到元素的哈希值 ,然后通过元素的哈希值经过移位等运算,就可以算出该元素在哈希表中的存储位置
    1. 如果算出的元素存储的位置目前没有任何元素存储,那么该元素可以直接存储在该位置上;
    2. 如果算出的元素的存储位置目前已经存在有其他的元素了,那么还会调用该元素的equals方法
      与该位置的元素再比较一次,如果equals方法返回的是true,那么该位置上的元素视为重复元
      素,不允许添加,如果返回的是false,则允许添加
  3. 例子:该对象的 age 字段与之前已经添加的一个 age 字段为 18 的对象相同,且哈希码也相同,所以 HashSet 认为它们是同一个对象,因此不会将其添加到集合中,返回的结果是 false
class Person {
	String name;
	int age;
	private void Peron() {
		// TODO Auto-generated method stub
 
	}
 
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
 
	@Override
	public int hashCode() {
		System.out.println("--------");
		// TODO Auto-generated method stub
		return this.age;
	}
 
	@Override
	public boolean equals(Object obj) {
		System.out.println("---****----");
		Person p = (Person)obj;
		return this.age == p.age;
	}
 
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "{姓名:"+name+"年龄:"+age+"}";
	}
}
public class Demo2 {
	public static void main(String[] args) {
		HashSet set = new HashSet();
		set.add(new Person("yy",18));
		set.add(new Person("xx",19));
		set.add(new Person("zz",20));
		set.add(new Person("jj",25));
		System.out.println("添加元素成功了嗎?"+set.add(new Person("zhangsan",18)));
		System.out.println("集合的元素:"+set);
	}
}

10.4总结

  1. 存储对象:HashSet 存储对象采用哈希表的方式,它不允许重复元素,即集合中不会包含相同的元素。当向 HashSet 中添加元素时,会根据元素的 hashCode() 方法和 equals() 方法来判断元素是否重复。
  2. 底层数据结构:HashSet 的底层数据结构是基于 HashMap 实现的,实际上 HashSet 的元素就是作为 HashMap 的 key 存储的。
  3. null 值问题:HashSet 允许存储一个 null 元素。
  4. 线程安全问题:不安全
  5. 当我们试图把某个类的对象当成 HashMap的 key,或试图将这个类的对象放入 HashSet 中保存时,重写该类的equals(Object obj)方法和 hashCode() 方法很重要,而且这两个方法的返回值必须保持一致:当该类的两个的 hashCode() 返回值相同时,它们通过 equals() 方法比较也应该返回 true。通常来说,所有参与计算 hashCode() 返回值的关键属性,都应该用于作为 equals() 比较的标准。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言实现快速排序算法

1. 什么是快速排序算法 快速排序的核心思想是通过分治法&#xff08;Divide and Conquer&#xff09;来实现排序。 算法的基本步骤是: 1. 选择一个基准值&#xff08;通常是数组中的某个元素&#xff09;&#xff0c;将数组分成两部分&#xff0c;使得左边的部分所有元素都小于…

2024.4.1-[作业记录]-day06-认识 CSS(三大特性、引入方式)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; day06-认识 CSS(三大特性、引入方式) 文章目录 day06-认识 CSS(三大特性、引入方式)作业…

xss.pwnfunction-Ma Spaghet!

根据代码得知 这个是根据get传参的并且是由someboby来接收参数的 所以 <script>alert(1137)</script> js并没有执行因为 HTML5中指定不执行由innerHTML插入的<script>标签 所以 ?somebody<img%20src1%20onerror"alert(1337)"> 这样就成…

Java栈和队列的实现

目录 一.栈(Stack) 1.1栈的概念 1.2栈的实现及模拟 二.队列(Queue) 2.1队列的概念 2.2队列的实现及模拟 2.3循环队列 2.4双端队列&#xff08;Deque&#xff09; 一.栈(Stack) 1.1栈的概念 栈:一种特殊的线性表&#xff0c;其 只允许在固定的一端进行插入和删除元素操作…

JavaWeb--JavaScript Part 01

1. JavaScript概述 JavaScript&#xff08;简称JS&#xff09;是一种轻量级的、解释执行的客户端脚本语言&#xff0c;主要用于增强网页的交互性和动态性。它起源于Netscape的LiveScript&#xff0c;并在1995年发布时更名为JavaScript。尽管名称中包含"Java"&#xf…

JS 利用 webcam访问摄像头 上传到服务器

webcam JS 较为详细的指南 定义标题 <!doctype html> <html> <head><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>How to capture picture from webcam with Webcam.js</title></…

FreeMarker系列--指令的用法(全面,有示例)

原文网址&#xff1a;FreeMarker系列--指令的用法(全面&#xff0c;有示例)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍FreeMark指令的用法。 相关网址 中文官方参考手册 assign 描述 使用该指令你可以创建一个新的变量&#xff0c; 或者替换一个已经存在的变量。注…

Redis实现高可用持久化与性能管理

前言 在生产环境中&#xff0c;为了实现Redis的高可用性&#xff0c;可以采用持久化、主从复制、哨兵模式和 Cluster集群的方法确保数据的持久性和可靠性。这里首先介绍一下使用持久化实现服务器的高可用。 目录 一、Redis 高可用方法 1. 持久化 2. 主从复制 3. 哨兵 4.…

2024.4.5-[作业记录]-day10-CSS 布局模型(层模型)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业 2024.4.5-学习笔记1 CSS定位1.1 相对定位 relative1.2 绝对定位 absolut…

【C++】map set 底层刨析

文章目录 1. 红黑树的迭代器2. 改造红黑树3. map 的模拟实现4. set 的模拟实现 在 C STL 库中&#xff0c;map 与 set 的底层为红黑树&#xff0c;那么在不写冗余代码的情况下使用红黑树同时实现 map 与 set 便是本文的重点。 1. 红黑树的迭代器 迭代器的好处是可以方便遍历&…

Day84:服务攻防-端口协议桌面应用QQWPS等RCEhydra口令猜解未授权检测

目录 端口协议-口令爆破&未授权 弱口令爆破 FTP&#xff1a;文件传输协议 RDP&#xff1a;Windows远程桌面协议 SSH&#xff1a;Linux安全外壳协议 未授权案例(rsync) 桌面应用-QQ&WPS&Clash QQ RCE 漏洞复现 WPS RCE 漏洞复现 Clas* RCE 漏洞复现 知识点…

90天玩转Python—04—基础知识篇:Python编程基础:标识符、保留字、注释、多行语句、print输出以及模块导入详解

90天玩转Python系列文章目录 90天玩转Python—01—基础知识篇:C站最全Python标准库总结 90天玩转Python--02--基础知识篇:初识Python与PyCharm 90天玩转Python—03—基础知识篇:Python和PyCharm(语言特点、学习方法、工具安装) 90天玩转Python—04—基础知识篇:Pytho…

淘宝里的优惠券在哪里查看_淘宝优惠券怎么找到领取

淘宝里的优惠券在哪里查看&#xff1f; 1、打开手机淘宝APP&#xff0c;点击右下角我的淘宝&#xff1b; 2、在我的淘宝里找到我的权益&#xff0c;看到优惠券后点击进入&#xff1b; 3、我淘宝我的权益券里可以看到已领取到的淘宝天猫优惠券&#xff1b; 淘宝优惠券怎么找到领…

开源代码分享(17)-基于足球队训练算法(Football Team Training Algorithm,FTTA)的组合风速预测

参考文献&#xff1a; [1]Tian Z, Gai M. Football team training algorithm: A novel sport-inspired meta-heuristic optimization algorithm for global optimization[J]. Expert Systems with Applications, 2024, 245: 123088. 1.算法基本原理 足球队训练算法&#xff0…

(学习日记)2024.04.01:UCOSIII第二十九节:消息队列实验(待续)

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

独角数卡对接码支付收款教程

1、到码支付后台找到支付配置。2、将上面的复制依次填入&#xff0c;具体看下图&#xff0c;随后点立即添加 商户ID商户PID 商户KEY异步不能为空 商户密钥商户密钥

jenkins_Pipeline使用测试

jenkins—Pipeline使用测试 安装jenkins # jar包启动 https://sg.mirror.servanamanaged.com/jenkins/war-stable/2.346.1/jenkins.war https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz [rootvm ~]# tail /etc/profile ... export JAVA_HOME/opt…

51单片机入门:LED点阵屏

LED点阵屏介绍 LED点阵屏由若干个独立的LED组成&#xff0c;LED以矩阵的形式排列&#xff0c;以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种场合&#xff0c;如&#xff1a;广告屏、公告牌等。 分类&#xff1a; 按颜色&#xff1a;单色、双色、全彩&#x…

GPT4解除限制使用次数了!GPT5预计要推出了!

今天登录GPT Plus的时候&#xff0c;出现了如下提示&#xff1a; With DALLE,browing and analysis Usage limits may apply GPT4已经没有了数量和时间限制的提示。 更改前&#xff1a;每 3 小时限制 40 次&#xff08;团队计划为 100 次&#xff09;&#xff1b;更改后&#…

尚硅谷html5+css3(1)

1.基本标签&#xff1a; <h1>最大的标题字号 <h2>二号标题字号 <p>换行 2.根标签<html> 包括<head>和<body> <html><head><title>title</title><body>body</body></head> </html> 3…