java集合的底层实现

    xiaoxiao2025-04-19  9

    ArrayList (1)底层采用数组实现,若使用不带参数的构造方法,则生成长度为10的Object类型数组。 (2)若个数超过10,则生成一个新数组,长度为原数组的1.5倍+1,原数组的内容复制到新数组中。 (3)删除时,后续前移,代价高。 HashMap (1)HashMap是基于哈希表的Map接口的非同步实现(Hashtable跟HashMap很像,唯一的区别是Hashtable中的方法是线程安全的,也就是同步的)。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 (2)在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表的数组”的数据结构,每个元素存放链表头结点的数组,即数组和链表的结合体。 (3)往HashMap中put元素的时候,先根据key的hashCode**重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾**。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。 (4)当get元素时,先计算key的hashcode(自定义的方法),找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。 (5)hash算法 key为null时,则调用putforNullKey方法,放入table[0]中。 若不为空,则int hash=hash(key.hashcode())。 这样做的目的是:改进传统的hash方法,尽量保证key的每一位都会影响到最后的hash值,以减少hash冲突。 注意:为什么capacity是2的倍数? 答:因为数组大小为2的次方时,访问性能最高,不同的key算的Index相同的几率较小,数据分布较均匀,碰撞的几率小,相对的,查询的时候就不用遍历某个位置的链表,这样查询效率高。当length总是 2 的n次方时,h& (length-1)运算等价于对length取模,也就是h%length,但是&比%具有更高的效率。8 & (15-1)和9 & (15-1)都得到0100,而8 & (16-1)和9 & (16-1)得到的是0100,0101,所以碰撞几率小。 (5)resize 当元素个数n>length*loadFactor时,进行扩容,直接扩大1倍,然后重新计算每个元素在数组中的位置,但是重新定位是非常耗时的,因此在预知元素个数时,那么最好预设元素的个数。如已知1000个元素,系统默认是1024,然而这并不合适,因为当750时就要进行扩容,所以应设置为2048。

    转载请注明原文地址: https://ju.6miu.com/read-1298228.html
    最新回复(0)