文章目录
参考视频
1.双列集合概述
1.1.整体总述
-
HashTable、ConcurrentHashMap:线程安全的HashMap;
-
HashMap:
— JDK1.7:数组 + 链表;
— JDK1.8+:数组 + 链表 + 红黑树;
-
LinkedHashMap:数组 + 双向链表;
-
TreeMap:数组 + 红黑树。
1.2.双列集合选型
-
键无序:
– 效率更高:HashMap,数组 + 链表 ( + 红黑树 ),>=8树化,<=6退化;
– 线程安全:ConcurrentHashMap:相比HashTable性能更佳;
------ HashTable使用synchronized阻塞线程,当并发量过多时性能急剧下降;
------ JDK1.7:分段锁,相当于将ConcurrentHashMap分成多段,只锁其中一小段;
------ JDK1.8:舍弃分段锁,采用CAS + synchronized。
-
键有序:
– 存取同序:LinkedHashMap,数组 + 双向链表;
– 自然排序:TreeMap,数组 + 红黑树。
-
读取配置:Properties。
2.双列集合遍历方法
2.1.与遍历相关的Map接口简介
Map接口中有几个比较重要的与遍历相关的方法:
- Map.keySet( ):获取 存储所有Map中Key的Set集合;
- Map.values( ):获取 存储所有Map中Value的Collection集合;
- Map.entrySet( ):获取 存储所有Map中结点的Set集合;
而本文中重点讲的ConcurrentHashMap、Properties、HashMap、LinkedHashMap、TreeMap都是Map接口的实现类,必然都有实现这些方法。
2.2.以HashMap为例,实现三种遍历
重要的内部类有四个,其中三个常用于遍历。假设实例化一个HashMap对象,其引用为map:
- **HashMap N o d e ∗ ∗ < / f o n t > : 实 现 了 M a p Node**</font>:实现了Map Node∗∗</font>:实现了MapEntry接口,即结点,属性有hash、key、value、next。
- HashMap$KeySet:实现了Set接口,调用map.keySet( )获取该类对象,可获取所有的Key。
- HashMap$Values:实现了Collection接口,调用map.values( )获取该类对象,可获取所有的Value
- HashMap$EntrySet:实现了Set接口,调用map.entrySet( )获取该类对象,可直接获取完整的结点数据。
3.Map接口概述
3.1.操作Map的抽象方法
简单介绍一下Map接口中操作Map的抽象方法:
- Map.put(K, V):新增,如果结点已存在则会替换结点的value;
- Map.putAll(Map<K, V>):拆开参数中的Map,逐个添加结点;
- Map.remove(K):根据Key删除结点;
- Map.get(K):根据Key获取Value值。
3.2.新增结点规则
所有Map结构都是【数组 + 另一数据结构】,新增结点时,他们共有的规则如下:
- 对结点的key调用key.hashCode( )计算hash值,再根据公式(与数组长度有关)计算数组下标;
- 确定数组下标后,遍历其中的另一数据结构(HashMap为链表/红黑树),逐个调用value.equals(Object)判断是否相等:相等时替换value值,均不等时添加结点。
正因如此,所有的自定义类都应该重写equals( )和hashCode( )方法。
4.Map实现类概述
4.1.HashMap - 无序,效率高,线程不安全
JDK1.7时,其底层结构是 数组+链表;
JDK1.8+时,其底层结构是 数组 + 链表 + 红黑树。
HashMap是重点内容,了解详细内容请移步14.HashMap新增结点机制、扩容机制、树化机制。
4.2.LinkedHashMap - 存取同序
继承自HashMap,底层结构为 数组 + 双向链表。
4.3.TreeMap - 默认自然排序
底层结构是 数组 + 红黑树,无参构造时采用自然顺序(字典序)进行排序。
4.4.HashTable / ConcurrentHashMap - 无序,线程安全
底层结构与HashMap一致,
-
HashTable使用synchronized保证线程安全,并发量过大时性能急剧下降,几乎已被舍弃。
-
ConcurrentHashMap是HashTable的优化版,不同版本采用不同的线程安全机制:
— JDK1.7:分段锁,相当于将ConcurrentHashMap分成多段,只锁其中一小段;
— JDK1.8:舍弃分段锁,采用CAS + synchronized。
4.5.Properties - 无序,线程安全,读取文件
继承自HashTable,常见的应用场景是:读取xxx.properties文件,并将其中的键值对封装成Properties对象。