Map

map中的key:无序,不可重复的 --》:key方法需要重写hashcode和equals方法

map中的value:无序,可重复的

一个键值对构成一个entry对象,entry对象无序不可重复

HashMap

hashmap底层的数据结构:

jdk7及之前:数组+链表

jdk8及之后:数组+链表+红黑树

JDK7为例:

实例化以后底层创建了长度为16的一维数组Entry[] table;

map.put(k1,v1);

首先,调用k1所在类的hashcode()计算k1的哈希值,此哈希值通过算法计算以后得到entry()数组所在的存放位置

如果计算得到的这个位置为空,此时的k-v(entry)直接添加成功 ----------情况一

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

如果k1的哈希值与已经存在的数据hash值都不相同,此时k1-v1添加成功 -------情况二

如果k1的哈希值和已经存在的某个哈希值相同,调用k1所在类的equals方法,比较:

如果equals返回false,则k1-v1添加成功 ---------情况三

如果equals方法返回true,则说明key值相等,使用v1替换相同key的value值

补充:关于情况二和情况三:此时的k1-v1和原来的数据以链表的方式存储

扩容:在不断的添加过程中,会涉及到扩容问题,默认的扩容方式扩容为原来的2倍,并将原有的数据复制过来

JDK8相较JDK7不同:

1.new hashmap():底层没有马上创建长度为16的数组

2.jdk8底层的数组类型是Node类型(其实元素类型一样,名字不一样)

3.首次调用put方法时,底层才创建长度为16的数组(参考Arraylist,一样的处理方式)

4.jdk底层结构只有数组+链表,jdk8底层数据结构有数组+链表+红黑树

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