Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >java集合(二)--set收尾+HashMap

java集合(二)--set收尾+HashMap

作者头像
阑梦清川
发布于 2025-02-24 07:00:30
发布于 2025-02-24 07:00:30
890
举报
文章被收录于专栏:学习成长指南学习成长指南

1.linkedhashset的介绍

下面的这个就是我们的linkedhashset的结构示意图,和我们之前介绍的这个hashset相比之下,这个linkedhashset的区别就是我们的这个linkedhashset是一个双向链表的结构;

下面的这个我们是首先插入了一个AA这个内容,然后是插入这个456,接着插入456这个时候可能计算这个hash值之后这个就无法继续插入了,因为这个已经存在了,我们创建一个新的对象,然后添加这个123,hsp这个字符串,在这个过程中,我们每一次添加一个元素,这个元素就会和上一个加入的数据构成双向的链表;

因此这个

插入和打印输出的顺序问题:我们上次介绍的这个hashmset插入数据的顺序和我们的打印输出的顺序是一致的,就是因为我们的这个链表是一个双向的链表,这个节点的顺序就是确定的;

image-20241018163333758
image-20241018163333758

2.linkedhashset源码分析

linkedhashset底层就是linkedhashmap(这个是hashmap的子类);

entry是这个底层的数据类型,table数组是这个node类型的,因此两者之间应该是存在某种关系的,table数组的最开始的大小就是16,和我们之前介绍的这个hashset最开始的空间大小是一样的;

image-20241018191530856
image-20241018191530856

我们的这个每一个数据entry就是我们的这个linkedhashmap的子类,因此我们的这个table数组是node类型的,我们的这个hashmap.node可以通过这个hashmap类进行访问,因此这个node类就是一个静态内部类(不属于对象,而是属于这个类,可以直接使用类进行访问)相当于这个entry是我们的这个hashmap下面的静态内部类node的一个子类;

image-20241018192537094
image-20241018192537094

下面的这个table就是我们的数组node类型的,0表示的就是数组下标entry类型的:

image-20241018193008995
image-20241018193008995

双向链表的节点之间连接方式,在这个调试过程中也是可以看到的,就是这个before和after,在我们插入第一个数据的时候,两个都是空的,当我们插入第二个数据的时候,这个里面的after就已经有了自己的指向,就不是null了,而是指向新的位置;

image-20241018193058168
image-20241018193058168

3.Map的基本介绍

31.基本属性

  • map里面是有类似于这个键值对的内容组成的,key不可以重复,但是不同的key可以对应相同的value数值的;
  • map里面的这个key可以是空的null,value也可以是null,但是我们的这个为null的key只能有一个,这个为null的value可以有多个;
  • 通常情况下我们使用string,但是绝不仅仅只有这个string可以是我们的key,只要是object的子类就可以;
  • 通过map.get方法可以得到这个对应的value数值,例如使用这个map.get(no1)就可以得到这个hsp这个value数值;
  • 当插入的数据的key和已经存在的一样,但是这个value不一样的时候,这个新插入的数据会把原来的这个value替换掉,但是这个key不变化,因为两个是一样的;
  • hashmap属于线程不安全操作;
image-20241018194727736
image-20241018194727736

我们的这个table还是数组,是node类型的,这个里面的数组元素是node类型的;

image-20241018195118025
image-20241018195118025

我们可以看到这个node实际上是实现了这个entry这个接口的,这个静态类里面包含了这个hash,key,value和我们的next指针指向下一个元素;

image-20241018195554756
image-20241018195554756

下面的这个就是数组是node类型的,我们通过转换为这个entry放到这个set里面去,然后这个set里面有这个set(引用)和collection方便对于我们的键和值进行管理;

image-20241018200933520
image-20241018200933520

下面的这个是往这个集合里面添加了两个基本的数据和这个new的对象;

image-20241019092700501
image-20241019092700501

我们可以看到,我们添加基本的数据的时候,还不可以从这个地址上面看到这个引用的关系,但是当我们new这个对象的时候,就会发现这个entryset里面的这个元素的地址和我们的这个table元素的这个对应的地址是一样的,因此可以证明这个就是一个引用的指向关系,这个entryset指向了这个hashmap$node里面的对应的位置;

image-20241019092816267
image-20241019092816267

3.2map里面的集合以及内部数据类型

深度分析:

  • 第一次学习这个entryset的时候,也是非常的迷惑,其实这个entryset就是一个集合,这个结合里面的就是我们的这个entry数据;
  • 我们知道在这个map里面,是有这个key-value组成的,我们下面的介绍就把这个key-value简称为这个k-v;
  • 上面说到的这个entry实际上就是一个k-v,也就是说这个每一个entry都是一个k-v,然后这个所有的k-v组合在一起成为了entry这个集合;
  • 上面的这个叙述转换为编码就是EntrySet<Map.Entry>,其中这个entryset里面的这个定义的类型是map.entry,但是这个实际上的存放的类型还是这个hashmap$node类型的数据;
  • 为什么上面的这一点里面的存放数据的类型和我们的定义类型不一致,这个主要就是因为我们的这个hashmap
node实现了这个map.entry的接口,因此这个hashmap

entry的实例化对象可以赋值给这个hashmap$node的接口(这个是接口的一个规则语法);

  • 也就是说上面的这个图里面,我们的这个hashmap$node是实际存放的数据类型,但是这个会被转换为这个entry数据类型,然后放到我们的这个set里面去即可;
  • 为什么会创建这个entryset集合,这个主要就是因为方便我们程序员进行这个集合的遍历,因为这个entryset里面有这个getValue和getKey的方法;

4.Map接口的常见方法

  • map接口的方法,就是这个往集合里面放进去元素,使用这个put方法;
  • 删除这个map的数据,使用的就是我们的这个remove方法;
  • 清除键值对,可以使用这个clean方法;
  • 可以使用这个iscontainkey判断是不是包含这个键;
  • size方法可以用来获取这个集合里面的entry的个数,其中这个entry就是一个k-v;
image-20241018204744734
image-20241018204744734

5.map里面的遍历的方法

5.1根据key直接遍历

下面的就是使用增强for和迭代器两个方式,通过拿到这个key,使用这个对应的方法得到这个values;

image-20241019091417389
image-20241019091417389

5.2直接拿到这个value值

这个里面就是直接调用这个map.values方法得到这个values数值,然后使用两个方式进行这个结果的打印输出;

image-20241019091623040
image-20241019091623040

5.3使用这个entry遍历

我们下面的这个就是上面介绍的这个实现接口的是类的实例化对象可以传递给这个接口,但是我们需要把这个数据强制转换为这个map.entry类型的;

然后这个entry就可以去调用这个getkey和getvalue方法得到这个对应的键值情况;

image-20241019091716254
image-20241019091716254

6.hashmap扩容转化红黑树的模拟

image-20241019095954599
image-20241019095954599

hashmap扩容原理和之前的这个hahset完全一样;

image-20241019095923870
image-20241019095923870

这个主要是一个怎么样的过程呢?就是:

  • 首先我们进行的这个类的定义的时候,返回值都是这个100,就是为了让他们计算的时候,数据都是在一个table的节点的这个链表上面,然后查看这个扩容的过程;
  • 我们首先就是16个大小,添加这个元素的过程中,会伴随着两次的扩容的过程,一次就是16----32一次就是从这个32------->64的过程;
  • 前面这两个扩容直到64的时候,这个节点的类型都是这个hashmap$node类型的,但是当我们的这个扩容达到了64之后继续插入数据,我们的节点的类型就是下面的这个显示的treenode类型的,这个时候已经是进行了这个红黑树的转化,这个就是树化的过程;
  • 因此在这个元素的添加的过程中,先是进行这个table数组的扩容的操作,然后是这个达到64之后,转换成为这个hashmap$treenode节点类型的红黑树;
image-20241019100240025
image-20241019100240025

7.hashtable底层介绍

  • 底层是这个hashtable$Entry[],初始化的大小是11;
  • hashtable线程安全,不允许是null值;
  • 下面的这个就是我们的hashtable的扩容的时候容量的变化:我们的这个原来的容量<<1表示的就是两倍+1即,这个扩容的过程就是在原来的这个11基础上面进行这个11*2+1=23的操作,因此这个扩容之后的大小就是23;
image-20241019110944896
image-20241019110944896

8.properties介绍

properties是我们的hashtable的子类,里面的这个数据也是k-v,里面数据也不可以是空的数据,如果相同的这个key后插入的这个value也会把原来的替换掉的;

properties通过这个get方法得到一个k-v里面的这个value数值,remove就是删除这个数据,因为两个相同的key也会把原来的value覆盖,因此可以使用插入相同的这个key去修改这个value数据内容;

9.集合的选型规则

学习了这么多的这个集合类型,我们如何进行选择:

首先判断这个是单列还是双列(k-v形式);

单列里面根据这个是否可以进行重复,分为了这个list和set结构,根据这个是否可以进行排序,分为了这个hashset和treeset结构;

在这个双列的结构里面,我们根据这个是不是有序的,是否可以进行排序,分为这个hashmap和treemap结构;

image-20241019112549481
image-20241019112549481
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java集合框架示意图
本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/210
joshua317
2021/12/13
6240
Java集合框架示意图
常用的几种java集合类总结
Java集合框架主要包括两种类型的容器,一种是集合(Collection),另一种是图(Map)。Collection接口又有3种子类型,List、Set和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等等。Map常用的有HashMap,LinkedHashMap等。
全栈程序员站长
2022/07/01
2900
常用的几种java集合类总结
Java集合深度解析之Hashtable
Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。 Hashtab
互扯程序
2018/03/26
1.1K0
Java集合深度解析之Hashtable
Java集合详解4:HashMap和HashTable
HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在。在HashMap中,key-value总是会当做一个整体来处理,系统会根据hash算法来来计算key-value的存储位置,我们总是可以通过key快速地存、取value。下面就来分析HashMap的存取。
Java技术江湖
2019/09/25
4340
程序员的20大Java集合面试问题及答案
Collection为集合层级的根接口。一个集合代表一组对象,这些对象即为它的元素。Java平台不提供这个接口任何直接的实现。
鱼找水需要时间
2023/12/23
1640
程序员的20大Java集合面试问题及答案
java集合详解完整版(超详细)「建议收藏」
联合整理 https://blog.csdn.net/feiyanaffection/article/details/81394745 https://www.cnblogs.com/linliquan/p/11323172.html
全栈程序员站长
2022/08/19
1.1K0
java集合详解完整版(超详细)「建议收藏」
java集合介绍_java代码分析框架
HashMap 是 Map 接口下一个线程不安全的,基于哈希表的实现类。由于他解决哈希冲突的方式是分离链表法,也就是拉链法,因此他的数据结构是数组+链表,在 JDK8 以后,当哈希冲突严重时,HashMap 的链表会在一定条件下转为红黑树以优化查询性能,因此在 JDK8 以后,他的数据结构是数组+链表+红黑树。
全栈程序员站长
2022/09/23
8070
java集合介绍_java代码分析框架
Java集合--HashMap解惑
3 Map 昨晚去了鸟巢,膜拜了5位40多岁的大爷们。算上这次,已是第三回了,每一次都有不同的感受、体验。期待,下一次的相遇。 说正题前,先附一张昨晚演唱会的图片! 今天,笔者要介绍的是Java集
贾博岩
2018/05/11
1.2K0
大厂必问的Java集合面试题
本文已经收录到github仓库,此仓库用于分享互联网大厂高频面试题、Java核心知识总结,包括Java基础、并发、MySQL、Springboot、MyBatis、Redis、RabbitMQ等等,面试必备!欢迎大家star!
程序员大彬
2022/01/06
1.5K0
大厂必问的Java集合面试题
Java集合源码分析(四)HashMap
一、HashMap简介 1.1、HashMap概述   HashMap是基于哈希表的Map接口实现的,它存储的是内容是键值对<key,value>映射。此类不保证映射的顺序,假定哈希函数将元素适当的分布在各桶之间,可为基本操作(get和put)提供稳定的性能。   在API中给出了相应的定义: //1、哈希表基于map接口的实现,这个实现提供了map所有的操作,并且提供了key和value可以为null,(HashMap和HashTable大致上是一样的除了hashmap是异步的和允许key和value为n
用户1195962
2018/01/18
9320
Java集合源码分析(四)HashMap
Java集合类
HashMap:它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap最多只允许一条记录的键为null,允许多条记录的值为null。HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。 JDK1.8中的结构为哈希桶数组(Node[] table)+链表+红黑树(采用链地址法解决hash冲突,红黑树减少拉链长度)
Monica2333
2020/06/22
4560
Java集合类原理实现
在java中所有的数据结构都可以使用数组和指针即引用来实现。而Hash也成散列,就是一个链表加数组实现。
石的三次方
2021/01/05
9160
Java集合框架(四)-HashMap
可以添加 null 的key 或者value,键只能由一个null,值可以由多个null;
化羽羽
2022/10/28
3420
深入理解JDK7 HashMap
在正式讨论HashMap之前,我们有必要把Map家族的继承实现关系展示出来,方便理解后续的内容。
itlemon
2020/04/03
6730
深入理解JDK7 HashMap
「 深入浅出 」集合Map
(最常用,随机访问速度快,无序,可存一个Null key,多个Null value,非同步)
KEN DO EVERTHING
2019/01/17
4650
Java 集合
Java 集合是一个常用的技术 ,无论是在: 开发使用,还是面试总是高频的提及到~
Java_慈祥
2024/08/06
1260
Java 集合
Java 集合框架(6)---- Map 相关类解析(下)
在上上篇文章中,我们看了一下 Java 集合框架中一些 Map 接口下的具体类,主要是对 HashMap 和 TreeMap 实现原理和相关元素操作流程的源码解析。接下来这篇文章中我们继续来解析 Java 集合框架中 Map 接口下的另一些具体类。Ok,话不多说,进入正题,还是先看图:
指点
2019/01/18
7340
Java 集合框架(6)---- Map 相关类解析(下)
Java集合源码浅析
由于 Collection接口直接继承了 Iterable,它是没有实现的,它的所有方法都是由它的子接口的实现类进行实现,所以这里就以 Collection下子接口 List的实现类 ArrayList来讲解。注意 List是有序集合且元素可以重复,而 Set则是无序集合,元素不可重复。
堆栈哲学
2022/11/23
4230
Java集合源码浅析
Java集合详解(List、Map、Set)
缺点: 指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。
是阿超
2021/10/15
5830
Java集合源码解析 - HashMap
HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长.
JavaEdge
2019/02/15
6410
Java集合源码解析 - HashMap
相关推荐
Java集合框架示意图
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档