HashMap原理及简单实现
public class MyHashMap<K, V> { private class Entry<K, V> { int hash; K key; V value; Entry<K, V> next; Entry(int hash, K key, V value, Entry<K, V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } } private static final int DEFAULT_CAPACITY = 1 << 2; private Entry<K, V>[] table; private int capacity; private int size; private final float loadFactor = 0.75f; public MyHashMap() { this(DEFAULT_CAPACITY); } @SuppressWarnings("unchecked") public MyHashMap(int capacity) { if (capacity < 0) { throw new IllegalArgumentException(); } else { table = new Entry[capacity]; size = 0; this.capacity = capacity; } } public int size() { return size; } public boolean isEmpty() { return size == 0 ? true : false; } public V put(K key, V value) { if (key == null) { throw new RuntimeException("key不可以为空!"); } if (size >= capacity * loadFactor) { // 开始rehash resize(2 * table.length); int hash = (null != key) ? hash(key) : 0; int index = indexFor(hash, table.length);// 注意此时的table已经扩容了 } V newValue = putEntry(key, value); return newValue; } @SuppressWarnings({ "rawtypes", "unchecked" }) private void resize(int newCapacity) { System.out.println("我们要扩容了!!当前的size是:" + size); // 让数组长度乘以两倍 Entry[] newTable = new Entry[newCapacity]; transfer(newTable, true); table = newTable; } @SuppressWarnings({ "rawtypes", "unchecked" }) private void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; for (Entry<K, V> e : table) { while (e != null) { if (rehash) { // 要重新hash e.hash = null == e.key ? 0 : hash(e.key); } int index = indexFor(e.hash, newCapacity); // 开始把e放进新的数组中 // 注意,每次插入新的值都必须要插在散列链表的头部 e.next = newTable[index]; newTable[index] = e; e = e.next; } } } private V putEntry(K key, V value) { if (key == null) { throw new RuntimeException("key不可以为空!"); } int hash = hash(key); int i = indexFor(hash, table.length); Entry<K, V> newEn = new Entry<K, V>(hash, key, value, null); 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))) { // 代表当前的e和要添加的key冲突了,那么就覆盖 V oldValue = e.value; e.value = value;// 当前的e的value要替换为新的value return oldValue; } } // 如果上面没有找到的话,就要往链表添加元素了 size++; addEntry(newEn, i); return value; } private void addEntry(Entry<K, V> entry, int index) { Entry<K, V> e = table[index]; table[index] = entry; entry.next = e; } public V get(K key) { if (key == null) { throw new RuntimeException("key不可以为空!"); } Entry<K, V> entry = getEntry(key); return null == entry ? null : entry.value; } private Entry<K, V> getEntry(K key) { if (size == 0) { return null; } int hash = (key == null) ? 0 : hash(key); 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))) { return e; } } return null; } public V remove(K key) { Entry<K, V> e = removeEntryForKey(key); return (e == null ? null : e.value); } private Entry<K, V> removeEntryForKey(K key) { if (size == 0) { return null; } int hash = (key == null) ? 0 : hash(key); int i = indexFor(hash, table.length); Entry<K, V> cur = table[i]; Entry<K, V> e = cur; while (e != null) { if (e.hash == hash && (e.key == key || key.equals(e.key))) { size--; // 如果删除的是prev的话 if (cur == e) { table[i] = e.next; } else { // 就让cur的next等于e的next cur.next = e.next; } return e; } cur = e; e = e.next; } return null; } private int indexFor(int hash, int length) { return hash & (length - 1);// 哈希值和长度减一做与运算 } private int hash(K key) { return key.hashCode(); } public static void main(String[] args) { MyHashMap<Integer, String> map = new MyHashMap<>(); } }