注意:Key和Value存储的不是值,而是对象地址,这个地址指向我们给他赋的值(涉及到自动装箱)!!!!
通过map.put(Key, Value)添加元素的底层实现:
第一步 :将Key, Value封装到Node对象中。
第二步:底层调用k的HashCode()方法返回Hash值,通过哈希算法得到一个数组的下标,如果数组的该位置处没有任何元素,那么就将该Node添加到数组的该位置,如果有元素,那么拿着该Node的Key和该数组位置的节点的Key进行equals()如果都为false,该节点被添加在链表的末尾,如果链表的某节点处为true,则利用该Node的Value值去覆盖当前的节点处的Value值。
map.get(key)方法的底层实现:
先调用Key的Hashcode方法得到哈希值,通过哈希算法得到对应的数组的下标,通过数组下标快速定位到某个位置上,如果这个位置上什么也没有,则返回null,如果这个位置上有单向链表,那么会拿着参数k和单项链表中的每个节点的k进行比较(equals()),如果所有的节点都返回false,那么最终该方法返回null,如果有一个节点的k和我们的k相匹配,那么该k节点所对应的value就是我们要找的value。
总结:拉链法处理冲突
hashMap集合Key部分特点:
在存储元素时需要重写Hashcode和equals方法。
无序不可重复。
放在hashMap集合的Key部分的元素实际上就是放到HashSet中了,所以hashSet中的hashcode和equals方法都需要重写。
放在HashMap的Key部分的元素和放在HashSet中的元素需要同时重写hashcode和equals()方法。
hashMap存储元素的特点:
HashMap初始化容量时16,默认加载因子为0.75,既当数组的容量占所有的容量的75%时,自动扩容,且HashMap初始化容量最好为2的倍数(官方推荐),才能达到冲突的几率最小。