伸缩性角度看HashMap:
1.HashMap
Hash 散列将一个任意的长度通过某种(hash函数算法)算法转换成一个固定值
移位法算出:
Map:地图 x,y, 存储
例:
总结:第一次放入Aa=1111,在Entry数组下标下标为4的地方放入,之后在放入BB=2222时,由于Aa与BB的hashcode相同,得到Entry数组下标也为4,就会在该位置插入BB=2222,并将BB=2222的next指向Aa=1111(执行②中BB的next指向Aa),最后再放入Aa=2222,又是数组下标为4,取该位置的Entry链表,取next,发现为Aa=1111,于是将Aa=1111更新为2222(执行①中for循环进行更新).。
1. key可以为空吗? 可以: NULL当成一个key来存储。
2.如果hash key重复了value会覆盖吗?
HashMap
会先用key
的hash值
来检查是否发生了hash碰撞
,也就是对应的位置是否为空,这个没问题。问题是当发生了hash碰撞
时,就会比较该位置上存储的每一个key
是否与新存入的相等,如果相等就替换之,否则就在该位置增加一个值。很明显,你代码中的前后两个key
是相同的,所以后面的会替换掉前面的。
所以HashMap
的时间复杂度并不是O(1)
,如果碰撞比较“激烈”那么其性能就会降低,解决办法是增加容量,从而减小碰撞几率,性能自然也就变高了。也就是所谓的空间换时间的做法。
3.hashmap什么时候做扩容?put的时候 高于或者等于0.75(因子系数)
偶数扩容:2的倍数做扩容的 第一次:16,第二次:2*16=32,第三次:2*32=64
4.Hashmap table: 数组+链表 数据结构
2.源码不足
2.1 :初始化容量 1左移4位 16容量
static final int DEFAULT_INITIAL_CAPACITY = 1<<4;
2.2: 最大的容量
MAXIMUM_CAPACITY = 1<<30;
2.3:加载因子系数 1分成四等分0.25 0.25*3=0.75 在容量的3/4时扩容
DEFAULT_LOAD_FACTOR = 0.75f;
3.手写实现
3.1.定义接口map
3.2.实现类hashmap
4.不足之处(伸缩性角度看)
时间复杂度:你的hash算法决定了你的效率
每当hashmap扩容的时候需要重新去add entry对象 需要重新hash,然后放入我们新的entry table数组里面
如果工作中知道hashmap需要存多少值,几千几万时最好先指定他们的扩容大小,防止在put的时候进行再次扩容
5.图解