/*
Map:双列数据,存储Key-Value
HashMap:作为Map的主要实现类,线程不安全但是效率高,可以存储null的key-value
LinkedHashMap:在原有的HashMap底层结构上,添加了一对指针,指向前一个和后一个元素
对于频繁的遍历操作,效率高于HashMap
TreeMap:可以按照添加的key-value对进行排序,实现排序遍历,考虑key的自然排序和定制排序
底层采用红黑树
HashTable:作为Map的古老实现类,线程安全但是效率低,不可以存储null的key-value
Properties:常用来处理配置文件,key-value都是String类型的
HashMap底层:数组+链表(JDK7及之前)
数组+链表+红黑树(JDK8)
Map结构理解:
Map中的key:无序的,不可重复的,使用Set存储所有的key(HashMap用HashSet,以此类推) -->要重写equals()和hashCode()方法
Map中的value:无序的,可重复的,使用Collection存储所有的value,要重写equals()
一个键值对:key-value构成了一个Entry对象
Map中的Entry:无序的,不可重复的,使用Set存储所有的Entry
HashMap底层实现原理:------>(以JDK7为例说明)
HashMap hashMap = new HashMap();
在实例化以后,底层创建了长度为16的一维数组Entry[] table.
map.put(key1,value1);
首先调用key1所在类的hashCode()计算key1的哈希值,此哈希值经过某种算法计算后得到在Entry数组中的存放位置
如果此位置上的数据为空,那么key1-value1添加成功
如果此位置上的数据不为空,比较当前key1和已经存在的key的哈希值
如果当前key1和已经存在的key的哈希值都不相同,那么key1-value1添加成功
如果当前key1和已经存在的某个key的哈希值相同,调用key1所在类的equals()方法,
如果equals()返回false,那么key1-value1添加成功
如果equals()返回true,那么将key1-value1替换原来的数据(修改操作)
补充:有数据存在时的添加成功,key1-value1和原有数据以链表的方式存储
在不断添加过程中,会涉及到扩容问题,默认的扩容方式:扩容为原来容量2倍,并将原有数据复制
JDK8在底层实现方面的不同:
1、HashMap hashMap = new HashMap();底层没有创建长度为16的数组
2、底层数组为Node[],而不是Entry[]
3、首次调用put()时,底层创建长度为16的数组
4、底层结构变为:数组+链表+红黑树
当数组某一个索引位置上的元素以链表形式存在的数据个数 >8 并且当前数组长度 >64时
此时此索引位置上的数据改为使用红黑树存储
优点:查询效率高