import java.util.Map;
import java.util.Objects;
public class HashMap
static final int DEFAULT_INITIAL_CAPACITY = 4;
static final int MAXIMUM_CAPACITY = 1 << 30; // 2 的 30 次方
static final float DEFAULT_LOAD_FACTOR = 0.75f;
int initialCapacity ;
float loadFactor;
int threshold;// 表单阈值
transient int size;
// 表单
static final HashMapEntry,?>[] EMPTY_TABLE = {};
transient HashMapEntry
public HashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity) {
this(initialCapacity,DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
if(initialCapacity<0){
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
}
if (initialCapacity>MAXIMUM_CAPACITY) {
initialCapacity=MAXIMUM_CAPACITY;
} else if(initialCapacity initialCapacity=DEFAULT_INITIAL_CAPACITY; } if(loadFactor<=0 || Float.isNaN(loadFactor)){ throw new IllegalArgumentException("Illegal load factor:"+loadFactor); } threshold = initialCapacity; } public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key ==null) { return putForNullKey(value); } // java 7 int hash = sun.misc.Hashing.singleWordWangJenkinsHash(key); // java 8 int hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); int h; int hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); int i = indexFor(hash,table.length); System.out.println("hash = "+hash +" i = "+i); for (HashMapEntry Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { System.out.println("override"); V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } addEntry(hash, key, value, i); return null; } public V get(Object key) { if (key == null) { System.err.println("return null"); return getForNullKey(key); } int h; int hash = (key == null) ? 0:(h = key.hashCode()) ^ (h >>> 16); for (HashMapEntry System.out.println("get key = "+ e.key); Object k; if (e.hash == hash && ((e.key == key || e.key.equals(key)))) { System.out.println(" return "+ e.getValue()); return e.getValue(); } } System.err.println("key is null"); return null; } private V getForNullKey(Object key) { if (size == 0) { return null; } for (HashMapEntry if (e.key == null) { return e.value; } } return null; } public V remove(Object key) { if (size == 0) { return null; } int h; int hash = (key == null) ? 0:(h = key.hashCode()) ^ (h >>> 16); int i = indexFor(hash, table.length); HashMapEntry HashMapEntry while (e!= null) { HashMapEntry Object k; if (e.hash == hash && ((k = e.key ) == key || (key != null && key.equals(k)))) { size -- ; if (prev == e) { table[i] = next; }else { prev.next = next; } return e.getValue(); } prev = e; e = next; } return e == null ?null: e.getValue(); } /** * Returns index for hash code h. */ private int indexFor(int hash, int length) { // System.out.println(String.format("hash = %d , length = %d", hash,length)); return hash & (length-1); } private void inflateTable(int toSize) { // Find a power of 2 >= toSize System.out.println("inflate table"); int capacity = roundUpToPowerOf2(toSize); float thresholdFloat = capacity * loadFactor; if(thresholdFloat > MAXIMUM_CAPACITY+1){ thresholdFloat = MAXIMUM_CAPACITY+1; } threshold = (int) thresholdFloat; table = new HashMapEntry[capacity]; } private int roundUpToPowerOf2(int number) { // assert number >=0 int rounded = number >= MAXIMUM_CAPACITY ? MAXIMUM_CAPACITY : (rounded = Integer.highestOneBit(number)) != 0 ? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded : 1; System.out.println("rounded = "+rounded); return rounded; } private V putForNullKey(V value) { for (HashMapEntry if (e.key == null) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } addEntry(0,null,value,0); return null; } private void addEntry(int hash, K key, V value, int bucketIndex) { if ((size >= threshold)&& (null != table[bucketIndex])) { resize(2 * table.length); int h; hash = (null != key)? (h = key.hashCode()) ^ (h >>> 16):0; // System.out.println("hash is "+ hash); } createEntry(hash,key,value,bucketIndex); } private void createEntry(int hash, K key, V value, int bucketIndex) { HashMapEntry table[bucketIndex] = new HashMapEntry size++; System.out.println("value = "+table[bucketIndex].getValue()); } private void resize(int i) { HashMapEntry[] oldTable = table; int oldCapacity = oldTable .length; if (oldCapacity == MAXIMUM_CAPACITY) { threshold= Integer.MAX_VALUE; return; } } static class HashMapEntry final K key; V value; HashMapEntry int hash; /** * Creates new entry. */ HashMapEntry(int h, K k, V v, HashMapEntry value = v; next = n; key = k; hash = h; } public final K getKey() { return key; } public final V getValue() { return value; } public final V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } public final boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e = (Map.Entry)o; Object k1 = getKey(); Object k2 = e.getKey(); if (k1 == k2 || (k1 != null && k1.equals(k2))) { Object v1 = getValue(); Object v2 = e.getValue(); if (v1 == v2 || (v1 != null && v1.equals(v2))) return true; } return false; } public final int hashCode() { return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()); } void recordAccess(HashMap } } } 测试 HashMap studentHashMap.put("lilei", 6); studentHashMap.put("wangwu",11); studentHashMap.put("lilei3", 12); studentHashMap.put("lilei4", 9); System.out.println(" lilei age "+ studentHashMap.get("lilei")); System.out.println(" wangwu age "+ studentHashMap.get("wangwu")); System.out.println(" lilei3 age "+ studentHashMap.get("lilei3")); System.out.println(" lilei4 age "+ studentHashMap.get("lilei4")); studentHashMap.remove("lilei"); System.out.println(" lilei age "+ studentHashMap.get("lilei"));