hash存储过程:
初始化:
1: 首先初始化hash结构, 初始化桶的个数和加载因子.
put(k, v):
1: 经过k的hashcode值再hash的获得h, 再和桶的长度进行indexFor(int h, int length),得出桶的index.
2: 至关于在桶的中寻找出合适的位置.
3: 在这个位置放下这个对象:table[i] = Entry(k, v), Entry其实是一个链表
4: 将数据放在链表的第一个位置. table[i].next =new Entry(k, v, oldValue).
5: 若是数据增长到临界值(初始大小*加载因子), 则须要从新建立之前2倍大小的桶(new_table=2*table).
6: 而后将table数据再拷贝到newtable中, 固然拷贝的只是table的索引.
get(k):
1: 经过k的hashcode值再hash的获得h和桶的长度(length). 再进行indexFor(int h, int length),得出桶的index.
2: 取出桶中的数据Entry,因为Entry是一个链表因此须要遍历出k的hash值和key都是相等的数据.java
//HashMap public HashMap() { //即上文说的加载因子(默认0.75) this.loadFactor = DEFAULT_LOAD_FACTOR; //默认大小(12 = 16 * 0.75) threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); //初始化桶的个数 table = new Entry[DEFAULT_INITIAL_CAPACITY]; init(); } //put方法: public V put(K key, V value) { if (key == null) return putForNullKey(value); //hashCode=> hash int hash = hash(key.hashCode()); //hash => index int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { //这个里面是特殊处理,若是存在旧数据, 则用的新的替换掉 Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; } void addEntry(int hash, K key, V value, int bucketIndex) { //取出之前数据 Entry<K,V> e = table[bucketIndex]; //对新的数据封装. table[bucketIndex] = new Entry<K,V>(hash, key, value, e); if (size++ >= threshold) //若是容量过大应该重建table结构. resize(2 * table.length); } void resize(int newCapacity) { Entry[] oldTable = table; int oldCapacity = oldTable.length; if (oldCapacity == MAXIMUM_CAPACITY) { threshold = Integer.MAX_VALUE; return; } Entry[] newTable = new Entry[newCapacity]; transfer(newTable); table = newTable; threshold = (int)(newCapacity * loadFactor); } //get public V get(Object key) { if (key == null) return getForNullKey(); int hash = hash(key.hashCode()); for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }