集合——Map接口

1.Map的实现类的结构

Map:双列数据,存储key-value对的数据

HashMap:作为Map的主要实现类;线程不安全,效率高,可以存储null的key和value。底层:数组+链表(jdk7及之前);数组+链表+红黑树(jdk8)

LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历,原因:在原有的HashMap底层结构基础上,添加了一对指针,只想前一个和后一个元素。对于频繁的遍历操作,执行效率高于HashMap。

TreeMap:保证按照添加的key-value对进行排序,实现排序遍历,此时考虑key的自然排序或定制排序。底层使用红黑树

Hashtable:作为古老的实现类,线程是安全的,效率低,不能存储null的key和value

Properties:常用来处理配置文件,key和value都是String类型

 

2.Map结构的理解

Map中的key:无序的、不可重复的,使用Set存储所有的key -> key所在的类要重写equals()和HashCode()方法(以HashMap为例)

Map中的value:无序的、可重复的、使用Collection存储所有的value -> value所在的类要重写equals()

一个键值对:key-value构成了一个Entry对象

Map中的Entry:无序的、不可重复的,使用Set存储所有的Entry

 

3.HashMap的底层实现原理(jdk7)

1.HashMap map = new HashMap();

  在实例化以后,底层创建了长度是16的一维数组,类型为Entry[]名字为table。

2.map.put(key1,value1);

首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算之后,得到在Entry数组中的存放位置。

  如果此位置上数据为空,此时添加成功。-------情况1

  如果此位置上的数据不为空(意味着此位置上存在一个或多个数据<以链表形式存在>),比较key1和已经存在的一个或多个数据的哈希值:

    如果都不相同,此时添加成功。--------情况2

    如果和某一个已经存在的数据(key2,value2)的哈希值相同,继续比较:调用key1所在类的equals(key2)方法,比较:

      如果返回false:添加成功。 --------情况3

      如果返回true:使用value1替换value2。

补充:关于情况2和情况3,此时key1-value1和原来的数据以链表的形式存储。

3.在不断的添加过程中,会涉及到扩容问题,当超出临界值且存放的位置非空时进行扩容,默认的扩容方式,扩容为原来的2倍,并将原有的数据复制过来。

jdk8相较jdk7的不同:

1.new HashMap():底层没有创建一个长度为16的数组,首次调用put()时才创建

2.jdk8底层的数组是Node[]而不是Entry[]

3.jdk8中的底层结构:数组+链表+红黑树

当数组的某一个索引位置上的的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时索引位置上的所有数据改为用红黑树存储,提高比较时的效率

 

你可能感兴趣的:(集合——Map接口)