hashmap中的底层数组为啥要保证时2的倍数
时间: 2023-06-17 10:05:02 浏览: 77
HashMap中的底层数组大小必须是2的幂次方,这是因为HashMap中使用了取模操作来确定某个元素在底层数组中的位置,这个位置的计算公式是 `hashcode(key) & (length-1)`,其中 `&` 代表位运算中的按位与操作。如果底层数组的长度不是2的幂次方,那么 `(length-1)` 的二进制表示中可能包含1和0,这样就无法保证取模的结果均匀分布了。而如果底层数组的长度是2的幂次方,那么 `(length-1)` 的二进制表示中所有位都是1,这样就可以保证取模的结果均匀分布了。因此,HashMap中的底层数组大小必须是2的幂次方。
相关问题
面试HashMap的底层原理
HashMap是基于哈希表实现的一种键值对存储结构。它的底层原理主要包括以下几个方面:
1. 哈希函数:HashMap使用哈希函数将key映射到数组下标。常见的哈希函数有取模法、乘法散列法、SHA等。
2. 数组:HashMap内部维护了一个数组用于存储键值对,通过哈希函数计算得到的下标就是该键值对在数组中的位置。
3. 链表:由于哈希函数的映射结果可能会出现重复,因此在数组中同一个下标位置可能会存储多个键值对。如果多个键值对映射到同一个下标位置,HashMap会使用链表将它们连接起来。
4. 扩容:在添加元素时,如果发现当前数组已经满了,HashMap会先将数组扩容一定的倍数,然后重新计算每个键值对在新数组中的位置,并将它们移动到新的位置上。
5. 线程安全:HashMap是非线程安全的,如果多个线程同时对同一个HashMap进行操作,可能会导致数据不一致的问题。可以使用ConcurrentHashMap来解决线程安全问题。
总的来说,HashMap的底层原理就是通过哈希函数将键值对映射到数组中的位置,使用链表处理哈希冲突,并在必要时扩容数组。
hashMap底层数据结构 ,负载因子,扩容倍数
HashMap的底层数据结构是数组和链表(或者红黑树,后面会详细说明)的组合,称为哈希表。数组用于存储元素,链表或红黑树用于解决哈希冲突。
负载因子(load factor)是指当前哈希表中已存储元素的数量与数组长度的比值。负载因子越大,表示哈希表中的元素越多,空间利用率也就越高。但是负载因子过大会导致哈希冲突的概率增加,影响查询和插入的性能。负载因子过小则会浪费空间。
在Java中,默认负载因子是0.75,即当哈希表中元素数量达到总容量的75%时,就会触发扩容操作。
扩容倍数(resize factor)是指哈希表在扩容时,将当前容量乘以扩容因子得到的新容量。在Java的HashMap中,默认的扩容倍数是2,即容量翻倍。
当哈希表需要扩容时,它会创建一个新的数组,并将所有元素重新计算哈希值后插入到新数组中。这个过程比较耗时,但可以提高哈希表的性能,因为新的数组长度增大了,减少了哈希冲突的概率。同时,根据链表的长度,当链表长度超过8时,链表会转换为红黑树,以提高查询性能。
总结起来,HashMap的底层数据结构是数组和链表(或红黑树)的组合,负载因子是当前元素数量与数组长度的比值,负载因子过大会增加哈希冲突的概率,负载因子过小会浪费空间。扩容倍数是在扩容时将当前容量乘以扩容因子得到的新容量,通过扩容可以提高哈希表的性能。
阅读全文