public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
hashmap继承abstractMap,实现map、Cloneable、Serializable
public abstract class AbstractMap<K,V> implements Map<K,V> {
abstractmap实现map
public interface Map<K,V> {
一、table变量
底层数据结构,是hashmap静态内部类Node的变量,node是一种数组加链表的底层数据结构
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
数组和链表有各自的优点
数组连续存储,寻址容易,插入删除操作相对困难。
链表离散存储,寻址相对困难,插入删除操作容易
hashmap结合这两种数据结构,在jdk8中,当链表长度(大于等于8的时候)太长,会转化为红黑树。链表时间复杂夫n,红黑树时间复杂的logn
二、entrySet变量
entrySet是EntrySet实体,定义为变量可保证不重复多次创建,是一个Map.Entry的集合,Map.Entry<K,V>是一个接口,Node类实现了该接口,EntrySet中方法操作的数据就是hashmap的Node实体
transient Set<Map.Entry<K,V>> entrySet;//变量entrySet
static class Node<K,V> implements Map.Entry<K,V> {//Node类实现了该接口
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;//保证不可重复多次创建
}
三、capacity
capacity不是一个成员变量,hashmap会用到这个概念,它的意思是容量
hashmap具有扩容机制,容量的规则是2的幂次,即capaticy是1,2,4,8.....
四、size
size变量记录了map中的key-value对的对数
五、threshold(阀)和loadfactor(负载系数)
threshold为临界值:threshold=capacity*loadfactor,超过临界值,就要扩容。
loadfactor(负载系数):装载因子,默认0.75f。
hashmap一些方法
一、put方法流程
hashmap的hash算法:是hashcode值与其hashcode值右移16位然后进行异或运算^得到的。这样使得冲突的概率变小。