HashMap

一基础知识
1.数组优势劣势
2.链表优势劣势
3.结合数组和链表优势的散列表
4.数组+链表+红黑树的hashmap

 

 

名称 优点 缺点 插入 读取
数组 下标读取快

扩容重新建

加塞插入的复杂度高

无序插入O(1)

有序插入O(n)+O(logn)

指定下标:O(1)

定值查找:O(n)

有序数组:O(logn)

链表

新增快

删除快

读取慢

头插O(1)

尾插O(n)

O(N)
散列表(hash)

新增快

删除快

查询快

哈希碰撞 O(1) O(1)

树->二叉树->查询二叉树->平衡二叉树->红黑树

插入还行

读取还行

存储大量数据复杂结构

平庸 O(logn) O(logn)

 

 

HashMap(1.8)    

关键方法
(1) final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict)
应用相关
拥有很快的插入速度和读取速度,在数据量庞大的时候尤为明显。所以适用大数据量,并对读写时间有要求的项目。

HashMap是否线程安全,代码出错原因,用什么数据结构可以解决线程安全问题

问题讨论:因为加载因子0.75存在,实际很难很难很难形成红黑树,0.25的null空位是必然(除非数组长度大道MAX_VALUE = 0x7ffffff)

 

问题 答案 对应代码部分 文字说明
扩容方法resize()真的会扩容吗? 已经扩容到最大数组长度则不会扩容2^30
树化方法treeifyBin()真的会树化吗?
数组长度小于64会首先resize()
put遇到重复key是如何替换的?      
new HashMap()会分配内存吗? 此一次插入数据时,才会对其赋值插入内存,new时为null
能否无限添加元素?能否无线扩容。 是,否 插入元素没有限制,扩容有2<<30(21亿多)
树化值是>=8还是>8(插入链表第九个元素树化还是第8个) 插入9进入树化方法  

 

 

 
 链表化是<=6还是<6 当数组长度为6链表化     
 为什么数组大小为2的整数幂?  快速散列    

按位与操作特点 ,2^n-1二进制为 ******111111,

直接散列分成当前数组个数

10101101

00000111

00000101 (0 1 10 11 100 101 110 111 8种情况)

 扰动函数hash(key)的目的是  更加散列  

无符号右移16位,为了让高16位参与散列

(数组长度低时候按位与操作只有后几位参与计算)

异或操作更加散列,

1010101010110101 0101011010111110

0000000000000000 1010101010110101

 tableSizeFor(int cap)方法 获取数组长度(2的n次幂长度)      

https://www.cnblogs.com/xiyixiaodao/p/14483876.html

1****************

11***************

1111************

11111111*******

............................... 简单理解把这个二进制都变成1

 

如果不cap-1 那么 1000 变1 后1111+1就多扩容一次

 final Node<K,V>[] resize() 关于链表这里处理方法 高位和地位思想      

  110101 ------

****111 ------ 101 原有数组长度-1按位与

***1111 ----- 0101 新长度-1按位与

***1000 ------0 旧长度按位与

posted @ 2022-05-13 11:27  zhyue  阅读(24)  评论(0编辑  收藏  举报