Map双列集合总结
这篇文章记录了学习Java过程中对Map集合的总结
一、Map
为什么叫双列集合?因为Map集合中每一个元素包含两个部分,一个是键(key)一个是值(value)
为什么Collecion是单列集合?因为Collention集合中每个元素就是一个单一的数据
二、HashMap
1. 底层结构----哈希表
1.1 特点
- 底层是哈希表就有哈希表所有特性:不重复,无序,查询快(只是针对键,对值没有要求)
- 可以null键null值,但null键只能有一个(因为不重复)
- 添加元素,键第一次出现是添加,第二次出现是修改
1.2 关于HashMap集合的基本常识
1.2.1默认容量:16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
1.2.2 默认负载因子:0.75
static final float DEFAULT_LOAD_FACTOR = 0.75f;
HashMap中元素达到这个比例时,进行扩容,新容量为之前两倍
- 负载因子衡量的是一个散列表(哈希表)空间的使用程度,负载因子越大表示散列表的装填程度越高,反之越小
- 如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费
- 默认负载因子0.75是对空间和时间效率的一个平衡的选择。当容量超过这个比例,resize后的HashMap容量是之前的两倍。
1.2.3 扩容机制
当hashMap中的元素越来越多时,哈希表的离散性就越来越低,发生哈希冲突的概率也越来越高,为了避免哈希冲突,提高查询效率,就会对哈希表进行扩容,扩容的过程时非常消耗性能的。所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能。
1.2.4 扩容过程
当集合中的数据长度达到容量的0.75倍时(
capacity * loadFactor
),会自动将HashMap容量扩大到原来的两倍,并且重新计算原哈希表中所有元素在新哈希表中的存储位置1.2.5 扩容过程分析
默认情况下,哈希表(数组)大小为16,loadFactor为0.75,那么当HashMap中元素个数超过16*0.75=12的时候,就把数组的大小扩展为 2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置
1.2.6 为什么建议在定义时候要声明容量
阿里开发规范
阿里巴巴《Java开发手册》第1章编程规范,第5节集合处理的第9条规定如下:
如果已知元素数量(假如128)但不指定容量(默认16),那么就会造成哈希表频繁的扩容造成性能降低。
1.2.7. 如何解决性能消耗
1、使用Google的Map工具类
//用在Maven里,需要导入坐标
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
Map<Integer, Integer> map2 = Maps.newHashMapWithExpectedSize(3);
map2.put(1, 1);
map2.put(2, 2);
map2.put(3, 3);
System.out.println("map2:" + map2);
2、在声明HashMap时就预设容量
HashMap map = new HashMap(8);//容量为2的幂次方
三、LinkedHashMap
1.1 特点:有序(指存取顺序)
1.2 底层实现----哈希表和链表
- 原理:底层结构依然是哈希表,只是每个键值对额外多了一个双链表机制,记录存储的顺序
四、TreeMap
1.1 特点:不重复,无索引,可排序(只能针对键排序)
五、比较难懂的方法
要说Map集合中比较难懂的方法,我相信很多同学在entrySet()方法上栽过跟头,在我第一次学的时候也被这个方法绕晕了,下面就重点解释一下:
这是官方的解释:返回一个此映射中包含的映射的set视图
Set<Map.Entry<K,V>> | entrySet() | Returns a Set view of the mappings contained in this map |
什么意思呢?也就是说,Map集合的元素是一个键值对,把这个键值对当作一个元素存到了Set集合中,可以看到Set集合他的泛型是一个Map.Entry<K,V>类型
看懂了木有,也就是说,把键值对当作一个整体,存放到了Set中,Set集合中每个元素就是一个键值对类型(这个词不准确哈,只是为了好理解)
Set集合中是一个Map.Entry<K,V>类型,就可以用Entry提供的方法获取键和值
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通