什么是map
是一种键值(key-value)映射表的数据结构
实现类
- HashMap Map主要实现类 线程不安全 效率高 可存储 null的key value
-
LinkedHashMap 保证在遍历map时 可以按照添加的顺序实现
在原有hashMap的基础上 添加了一对指针 指向前一个元素 和 后一个元素
对于频繁的遍历操作 LinkedHashMap 执行效率 高于 HashMap -
底层结构: 数组 + 链表(JDK7及之前) 数组 + 链表 + 红黑树(JDK8)
-
- TreeMap 排序 遍历
底层使用红黑树 - Hashtable 线程安全 效率低 不能存储null的key value
- Properties 常用来处理配置文件 key value都是String类型
Map特点
- key 无序 不可重复 跟set类似 key所在的类 要重写hashCode() 和 equals()方法 (HashMap举例)
- value无序 但是可以重复 使用Collection来存储所有value value所在的类需要重写equals()方法
- 一个key-value构成了一个Entry对象
- Map中的entry:无序的 不可重复 使用Set去存储所有的entry
HashMap实现原理
JDK7
HashMap map = new HashMap();
实例化后 底层创建了长度是16的一维数组Entry[] table
map.put(key1,value1);
首先 调用key1所在类的hashCode方法 此哈希值经过某种计算后 得到在数组的位置
如果该位置没有数据 `map.put(key1,value1);`添加成功
如果该位置有数据(最少有一个数据的存在) 比较key1和其他数据的哈希值是否相同
如果不相同 `map.put(key1,value1);`添加成功 情况2
如果和某个数据key2-value2相同 则比较key1 所在类的equals(key2)方法
如果返回值为false `map.put(key1,value1);`添加成功 情况3
如果返回值为true value1的值替换value2
情况2 和 情况3 此时的key1-value1和已经存在的数据以链表的方式进行存储
最后 在不断的扩容过程中 默认扩充为原来数组长度的两倍 将原来的数据 copy 过来
jdk8相比较于jdk7
new HashMap() 底层没有创建一个长度 16的数组
底层数组是Node[] 不是Entry[]
首次调用Put方法 创建长度为16的数组
当数组上某一索引的元素以链表的形式存在的数据个数 > 8 且当前数组长度 > 64时
此索引位置上的存储数据结构改为 `红黑树`存储
重要常量
DEFAULT_INITIAL_CAPACITY
默认容量 16MAXIMUM_CAPACITY
最大容量 230DEFAULT_LOAD_FACTOR
HashMap默认加载因子 0.75fthreshold
临界值 = 默认容量 * 加载因子TREEIFY_THRESHOLD
链表长度大于 此值时 转化为 红黑树 8MIN_TREEIFY_CAPACITY
被转化成红黑树最小数组大小 64