标签 Java编程 下的文章

HashMap 是线程安全的吗?多线程下会有什么问题?HashMap的线程不安全可能会引发以下问题:多线程下的扩容死循环:在JDK 1.7中,HashMap使用头插法插入元素,当多个线程同时进行扩容操作时,可能会导致环形链表的出现,进而形成死循环。为了解决这个问题,JDK 1.8改为使用尾插法插入元素,保持链表元素原本的顺序,避免了环形链表的问题。

- 阅读剩余部分 -

jdk1.8对HashMap主要做了哪些优化呢?为什么?JDK 1.8对HashMap进行了五点优化,具体如下:数据结构:数组+链表的组合改为了数组+链表或红黑树的组合。原因:当发生哈希冲突时,元素会被存储在链表中。但是当链表长度过长时,JDK 1.8会将链表转换为红黑树,从而将查找时间复杂度从O(n)降低到O(logn),提升性能。

- 阅读剩余部分 -

那扩容机制了解吗?HashMap是通过数组+链表和红黑树的组合实现的。在HashMap中,用于存放key值的桶数组的长度是固定的,由初始化参数确定。随着数据的插入数量增加和负载因子的作用,可能需要对HashMap进行扩容以容纳更多的数据。在扩容过程中,JDK 1.8引入了一项优化操作,可以避免重新计算每个元素的哈希值。

- 阅读剩余部分 -

你还知道哪些哈希函数的构造方法呢?HashMap中使用的哈希函数构造方法叫做除留取余法(modular hashing):除留取余法是指将关键字key除以一个不大于哈希表长度的正整数p(p <= N),然后取得余数作为地址。在HashMap中,进行了优化和改造,以提高效率和散列的均衡性。

- 阅读剩余部分 -

为什么HashMap的容量是2的倍数呢?有两个主要原因:方便哈希取余运算: 将元素放置在table数组中时,通常是通过计算hash值对数组大小取余来确定位置。在HashMap中,使用了hash值 & (数组大小-1)的位运算来定位元素,与使用取余操作达到相同的效果。而HashMap的容量选择为2的倍数,意味着该数的二进制表示只有一位为1,例如16(二进制为10000),32(二进制为100000),64(二进制为1000000)等。这样,通过将hash值 & (数组大小-1)进行位运算,就可以得到与取余操作相同的效果,并且位运算比取余操作更高效。

- 阅读剩余部分 -