Java进阶(Set)——面试时Set常见问题解读 结合源码分析

在这里插入图片描述

前言

List、Set、HashMap作为Java中常用的集合,需要深入认识其原理和特性。

本篇博客介绍常见的关于Java中Set集合的面试问题,结合源码分析题目背后的知识点。

关于List的博客文章如下:

  • Java进阶(List)——面试时List常见问题解读 & 结合源码分析

其他相关的Set的文章如下:

  • Java学数据结构(3)——树Tree & B树 & 红黑树 & Java标准库中的集合Set与映射Map & 使用多个映射Map的案例

目录

  • 前言
  • 引出
  • 1. 描述一下HashSet的底层原理?
    • 构造方法
    • add方法
  • 2. map.put方法,静态常量PRESENT
  • 3. map.remove key方法,PRESENT进行比较
  • 4. HashSet的去重原理?
  • 5. 如何选择HashSet 或 TreeSet?
  • 6. 如何得到一个线程安全的Set集合?
  • 总结

引出


1.特点:无序,去重,非线程安全;
2.底层:HashMap的Key值实现的;
3.map.put方法,静态常量PRESENT,新值替换旧值;
4.map.remove key方法,如果KEY不存在时,则返回的是null,如果KEY存在时,返回的就是e.value,即PRESENT,返回true成功,返回false不成功;
5.去重原理:先判断hash值,再通过==或者equals判断,整体如果返回true,则为重复元素;
6.无序的则采用HashSet ,有序的则采用TreeSet;
7.线程安全的set:Collections.synchronizedSet(new HashSet<>());

1. 描述一下HashSet的底层原理?

  1. HashSet的特点:无序,去重,非线程安全
  2. HashSet 底层是用HashMap的Key值实现的,也有上面的3大特征;

构造方法

无参和代参构造方法都会初始化这个HashMap

无参的构造方法,调用了HashMap方法

在这里插入图片描述

有参的构造方法也是,调用了HashMap方法

在这里插入图片描述

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上在这里插入图片描述

add方法

在这里插入图片描述

add方法中可以看出调用HashMap的put方法,key为放入元素,值为常量PRESENT

在这里插入图片描述

2. map.put方法,静态常量PRESENT

既然hashset基于hashmap实现,你说一下 hashset的add方法中,为什么要在map.put的val上放上一个Object类型的静态常量PRESENT?

在这里插入图片描述

HashSet底层调用了map的put方法,传入了存储的对象和PRESENT常量,那我们进入put方法继续查看

在这里插入图片描述

put方法内调用了putVal方法,PRESENT常量为形参value,继续进入查看

在这里插入图片描述

	if (e != null) { // existing mapping for key//把旧数据存储到oldValueV oldValue = e.value;//如果说存储的位置上已经有元素了if (!onlyIfAbsent || oldValue == null)//新元素会替代旧元素   新KEY替代KEYe.value = value;afterNodeAccess(e);//返回旧元素数据return oldValue;}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);//如果说上面的if结构没有执行,那么就说明这个位置上没有元素,则新增成功,返回nullreturn null;

在这里插入图片描述

在这里插入图片描述

public boolean add(E e) {//上面的方法返回值决定了HashSet的add方法到底返回true还是falsereturn map.put(e, PRESENT)==null;}
  1. 此方法内部明确箭头标处的原理,value就是PRESENT,如果进入这个if结构,则说明这个位置上已经存在该key,则会用value替换之前的旧值,然后返回旧值oldValue,否则会返回null;
  2. 至此,我们可以看出此方法的返回值是PRESENT或者是null,如果为PRESENT则说明KEY已存在,则add方法就会返回false(此处元素put还是成功的,只是新值替换旧值),返回null则add返回true,此KEY不存在,代表存储新的KEY-VALUE;

3. map.remove key方法,PRESENT进行比较

既然hashset基于hashmap实现,你说一下 hashset的remove方法中,为什么要在map.remove key 完了之后要和PRESENT进行一个等值比较呢?

在这里插入图片描述

在这里插入图片描述

  1. 从HashMap的remove方法中可以看出,方法返回的是e.value或者null,与add方法中的原理一起联想,则会明白,如果KEY不存在时,则返回的是null,如果KEY存在时,返回的就是e.value,即PRESENT
  2. 所以在HashSet在判断此返回值==PRESENT,如果相等则返回true,说明此KEY是存在的,删除成功返回true,如果返回值是null,那么null=PRESENT则返回的肯定是false,那么代表此KEY不存在,删除自然不成功,返回false;

在这里插入图片描述

public V remove(Object key) {Node<K,V> e;//判断了一下,如果removeNode删除得到的是null,说明此KEY不存在,方法返回nullreturn (e = removeNode(hash(key), key, null, false, true)) == null ?//否则返回e.value   就是 PRESENTnull : e.value;}
public boolean remove(Object o) {//因为HashMap删除成功返回的是PRESENT , ==PRESENT 则结果为true 代表删除成功//否则返回的是null , 返回false  删除失败return map.remove(o)==PRESENT;}

4. HashSet的去重原理?

在这里插入图片描述

  1. HashMap中putVal方法中有这么一段代码判断,去重原理在于hashcode的判断和equals方法的判断
  2. 先判断hash值,再通过==或者equals判断,整体如果返回true,则为重复元素

5. 如何选择HashSet 或 TreeSet?

无序的则采用HashSet ,有序的则采用TreeSet

6. 如何得到一个线程安全的Set集合?

Set datas = Collections.synchronizedSet(new HashSet<>());

在这里插入图片描述


总结

1.特点:无序,去重,非线程安全;
2.底层:HashMap的Key值实现的;
3.map.put方法,静态常量PRESENT,新值替换旧值;
4.map.remove key方法,如果KEY不存在时,则返回的是null,如果KEY存在时,返回的就是e.value,即PRESENT,返回true成功,返回false不成功;
5.去重原理:先判断hash值,再通过==或者equals判断,整体如果返回true,则为重复元素;
6.无序的则采用HashSet ,有序的则采用TreeSet;
7.线程安全的set:Collections.synchronizedSet(new HashSet<>());

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

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

相关文章

最短路径:迪杰斯特拉算法

简介 英文名Dijkstra 作用&#xff1a;找到路中指定起点到指定终点的带权最短路径 核心步骤 1&#xff09;确定起点&#xff0c;终点 2&#xff09;从未走过的点中选取从起点到权值最小点作为中心点 3&#xff09;如果满足 起点到中心点权值 中心点到指定其他点的权值 < 起…

Java学习_day05_数组

文章目录 一维数组概念初始化默认值动态赋值 二维数组概念初始化遍历数组 一维数组 数组是目前学习Java中&#xff0c;遇到的第一个引用对象。即在变量的存储空间中&#xff0c;存储的不再是数值&#xff0c;而是内存地址。这个内存地址指向实际对象的存储空间地址。 概念 …

Cocos Creator 中使用装饰器进行自动绑定

推荐一个偷懒的方式&#xff0c;使用装饰器自动绑定节点到脚本的属性 背景 用 Cocos Creator 写脚本组件的时候&#xff0c;有时需要场景中一个节点作为这个脚本的属性值。 按照官方文档推荐的方法&#xff0c;需要以下两步 添加一个 property 属性&#xff0c;在场景中拖入这个…

三维地图数据共享与统一存储

这家总部位于北京的高新企业是一家致力于三维数字地理技术的领军企业&#xff0c;提供中国领先的三维数据获取服务&#xff0c;并依据三维数据自动建模云计算服务、提供全国性的地图与位置服务。这项技术其实我们每天都有可能用到&#xff0c;例如百度地图、高德地图就属于三维…

基于标签的电影推荐算法研究_张萌

&#xff12; 标签推荐算法计算过程 &#xff12;&#xff0e;&#xff11; 计算用户对标签的喜好程度 用户对一个标签的认可度可以使用二元关系来表示&#xff0c;这种关系只有“是”“否”两种结果&#xff0c;实际上难以准确地表达出用 户对物品的喜好程度。因此&#x…

BUUCTF qr 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 这是一个二维码&#xff0c;谁用谁知道&#xff01; 密文&#xff1a; 下载附件&#xff0c;得到一张二维码图片。 解题思路&#xff1a; 1、这是一道签到题&#xff0c;扫描二维码得到flag。 flag&#xff1a;…

【23真题】大神凭这套拿452分!看看你能拿多少?

今天分享的是23年福州大学866的信号与系统试题及解析。23年福州大学新一代电子信息的最高分是452分&#xff01;但是我看不到单科分数。按照75&#xff0c;75&#xff0c;150&#xff0c;150。也就是只有450&#xff0c;说明这个同学&#xff0c;专业课和数学几乎拿满&#xff…

图纸管理制度《六》

为建立健全机运系统技术档案管理工作&#xff0c;完整的保存和科学地管理机运系统的技术档案&#xff0c;充分发挥技术档案在我矿建设发展中的作用&#xff0c;更好地为我矿个生产技术部门服务&#xff0c;特制定本管理制度. 1、要把图纸、技术档案管理工作纳入技术业务工作中…

火山引擎 ByteHouse:只需 2 个方法,增强 ClickHouse 数据导入能力

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 作为企业数字化建设的必备要素&#xff0c;易用的数据引擎能帮助企业提升数据使用效率&#xff0c;更好提升数据应用价值&#xff0c;夯实数字化建设基础。 数据导…

任正非说:扩张必须踩在坚实的基础上,擅自扩张只能是自杀。

嗨&#xff0c;你好&#xff01;这是华研荟【任正非说】系列的第23篇文章&#xff0c;让我们继续聆听任正非先生的真知灼见&#xff0c;学习华为的管理思想和管理理念。 一、要想赢&#xff0c;要么在剑法上高于人&#xff0c;要么在盾牌上坚于人。若果剑不如人&#xff0c;就要…

电脑怎么共享屏幕?电脑屏幕共享软件分享!

如何控制某人的电脑屏幕&#xff1f; 有时我们可能需要远程控制某人的计算机屏幕&#xff0c;例如&#xff0c;为我们的客户提供远程支持&#xff0c;远程帮助朋友或家人解决计算机问题&#xff0c;或在家中与同事完成团队合作。那么&#xff0c;电脑怎么共享屏幕&#xff…

物联网和互联网医院小程序:如何实现医疗设备的远程监测和管理?

物联网&#xff08;IoT&#xff09;技术的发展为医疗设备的远程监测和管理提供了巨大的机会。结合互联网医院小程序&#xff0c;我们可以实现对医疗设备的远程访问、监控和管理&#xff0c;从而提高医疗服务的质量和效率。本文将介绍如何实现医疗设备的远程监测和管理&#xff…

【ARMv8 SIMD和浮点指令编程】NEON 存储指令——如何将数据从寄存器存储到内存?

和加载指令一样,NEON 有一系列的存储指令。比如 ST1、ST2、ST3、ST4。 1 ST1 (multiple structures) 从一个、两个、三个或四个寄存器存储多个单元素结构。该指令将元素从一个、两个、三个或四个 SIMD&FP 寄存器存储到内存,无需交错。每个寄存器的每个元素都被存储。 …

分类预测 | Matlab实现KOA-CNN-BiLSTM-selfAttention多特征分类预测(自注意力机制)

分类预测 | Matlab实现KOA-CNN-BiLSTM-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09; 目录 分类预测 | Matlab实现KOA-CNN-BiLSTM-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09;分类效果基本描述程序设计参考资料 分类效果 基本描述 1…

【前端框架】本文带你了解nvue

前言 各位公主给&#x1f478;&#x1f3fb;&#xff0c;王子&#x1f934;&#x1f3fb;好&#xff0c;我是你们的Aic山鱼&#xff0c;专注于前端领域的垂直更新。我热衷于分享我的经验和知识&#xff0c;希望能够帮助更多的人在前端领域取得进步。作为一名前端开发人员&#…

腰背肌筋膜炎能彻底治愈吗

腰背肌筋膜炎&#xff1a;急性期腰部疼痛剧烈&#xff0c;有烧灼感&#xff0c;腰部活动时症状加重&#xff0c;局部压痛显著&#xff0c;有时体温升高、血液检查可见白细胞增高。急性发作后&#xff0c;少数患者症状完全消退&#xff0c;多数会遗留疼痛&#xff0c;或相隔数月…

负载均衡策略 LVS

一、集群功能分类 1、LB (1) 概念&#xff1a; LB&#xff1a;负载均衡 (Load Balancing) 是一种分发网络流量的技术&#xff0c;LB 负载均衡的基本原理是将传入的网络流量分发到多个后端服务器&#xff0c;以确保这些服务器都承担相似的工作负载&#xff0c;从而避免某一台…

关于报错java.util.ConcurrentModificationException: null的源码分析和解决

一般有这种问题,方法中至少会有List或者Map下的至少两个子类,有可能参数类型相同,也有可能不同都有可能触发这个问题!其主要原因是使用了ArrayList进行删除操作或者使用iterator遍历集合的同时对集合进行修改都有可能会出现这个问题 ArrayList属于List下的子类 需要区分的是Li…

1.让数组动起来

概述 对数组进行分析&#xff0c;目标如下 线性表的概念数组的存储结构数组查询&#xff0c;插入&#xff0c;删除操作的特点及对应的时间复杂度刷题(盛最多水的容器) 线性表 在数据结构中&#xff0c;数据的逻辑结构分为线性结构和非线性结构 线性结构: n个数据元素有序集合…