双列集合的分类:HashMap(无序,不重复,无索引)
,Hashtable,TreeMap
HashMap底层分析:HashMap的底层是由数组+链表+红黑树(Jdk8之后),当数组的长度超过64,链表的长度超过8时,HashMap的底层才会变为数组+链表+红黑树,其他情况是数组+链表
HashMap的扩容机制:Hash表中数组的分为手动初始化,和自动初始化,自动初初始会在第一次插入元素时开辟空间,默认长度为16,扩容因子为0.75,每次扩容量为自身的2倍长度,扩容之后存入数组的新索引位置就会改变。手动初始化的话,可以在创建对象时自定义初始数组长度,但HashMap不一定会自主设置的数值初始化数组,而按2的n次方创建。
HashMap的不重复,无序的原因:HashMap在添加键的时候,首先会根据键的地址空间调用HashCode()的方法,算出这个键的Hash值,如果后面再添加键的时候遇到相同的Hash值,就有一种情况添加值会成功,在Hash值相同的情况下,HashMap会对添加的值进行比较,如果Hash值相同,添加的值也相同,那么会添加失败,不同就会添加成功,这种情况称为Hash碰撞,这是HashMap保持不重复的原因。由于会根据键的地址空间调算出这个键的Hash值,在你创建对象的时候就会存在一个弊端,对象是一样的也会添加成功,因为new的时候空间地址是不一样的,所以Hash值会不一样。而解决这种情况就是你要在自定义对象中去重写HashCode()和eqsual()方法。无序的原因是添加的元素会根据Hash值去存放,就例如HashMap底层创建了3个长度数组,而你添加的10个元素都存放在前两个长度中,当你用迭代器遍历的时候,他会首先把长度为一的遍历完,这时候遍历出来的就是无序的。
LinkedHashMap(有序,不重复,无索引)实现有序的原理:
LinkedHashMap与与上面讲的HashMap其他原理基本相同,就多了一个原理,这个原理也是实现有序的原因。LinkedHashMap在存入元素的时候回比HashMap多一个数组来记录你存入元素的顺序,当你用迭代器的时候,他会按存入顺序的数组来遍历,去保证你的取出的顺序不会改变。
TreeMap(可排序,元素不可重复,无索引):
TreeMap的底层是红黑树,他会对你存入的元素进行排序。
使用场景:大多数情况下,一般都是用HashMap,因为在一般的使用环境下HashMap的效率是最高的。当你的项目需求要求排序的时候,你可以采用LinkedHashMap。当你需要对一些元素排序的时候你可以使用TreeMap