public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { /** * 默认初始化容量大小 */ static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; /** * 最大的容量 */ static final int MAXIMUM_CAPACITY = 1 << 30; /** * 默认的加载因子 */ static final float DEFAULT_LOAD_FACTOR = 0.75f; transient Set<Map.Entry<K,V>> entrySet; /** * 映射中包含的键值映射的个数。 */ transient int size; transient int modCount; /** * 要调整的下一个size (capacity * load factor) */ int threshold; final float loadFactor; /** * 初始化容器大小 * @return */ public HashMap(int initialCapacity, float loadFactor) { if(initialCapacity < 0) { throw new IllegalArgumentException("Illegal initial capacity: "+ initialCapacity); } if(initialCapacity > MAXIMUM_CAPACITY) { initialCapacity = MAXIMUM_CAPACITY; } if(loadFactor <= 0 || Float.isNaN(loadFactor)) { throw new IllegalArgumentException("Illegal load factor: "+ loadFactor); } this.loadFactor = loadFactor; this.threshold = tableSizeFor(initialCapacity); } static final int tableSizeFor(int cap) { int n = cap -1; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; } public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } public HashMap(){ loadFactor = DEFAULT_LOAD_FACTOR; }
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; } public final K getKey() { return key; } public final V getValue() { return value; } public final String toString() { return key + "=" + value; } public final int hashCode() { return Objects.hashCode(key) ^ Objects.hashCode(value); } public final V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } public final boolean equals(Object o) { if (o == this) return true; if (o instanceof Map.Entry) { Map.Entry<?,?> e = (Map.Entry<?,?>)o; if (Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue())) return true; } return false; } }