Map 接口
package util; import java.util.Collection; import java.util.Set; public interface Map<K, V> { int size(); boolean isEmpty(); boolean containsKey(Object key); boolean containsValue(Object val); V get(K key); V put(K key, V val); V remove(Object key); void putAll(Map<? extends K, ? extends V> map); void clear(); Set<K> keySet(); Collection<V> values(); Set<Map.Entry<K, V>> entrySet(); interface Entry<K, V> { K getKey(); V getValue(); V setValue(V val); boolean equals(Object o); int hashCode(); } boolean equals(Object o); int hashCode(); }
AbstractMap 抽象类
package util; import java.util.AbstractCollection; import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; import java.util.Set; /** * AbstarctMap 的方法实现都是靠遍历 entrySet 来确定带操作元素的位置 * 实际上 AbstractMap 实现的方法大部分都需要在子类中重写 * * @author alexis * * @param <K> * @param <V> */ public abstract class AbstractMap<K, V> implements Map<K, V> { protected AbstractMap() { } public int size() { return entrySet().size(); } public boolean isEmpty() { return size() == 0; } public boolean containsKey(Object key) { Iterator<Map.Entry<K, V>> i = entrySet().iterator(); if (key == null) { while (i.hasNext()) if (i.next().getKey() == null) return true; } else { while (i.hasNext()) { if (i.next().getKey().equals(key)) return true; } } return false; } public boolean containsValue(Object val) { Iterator<Map.Entry<K, V>> i = entrySet().iterator(); if (val == null) { while (i.hasNext()) if (i.next().getValue() == null) return true; } else { while (i.hasNext()) { if (i.next().getValue().equals(val)) return true; } } return false; } public V get(K key) { Iterator<Map.Entry<K, V>> i = entrySet().iterator(); if (key == null) { while (i.hasNext()) { Map.Entry<K, V> entry = i.next(); if (entry.getKey() == null) return entry.getValue(); } } else { while (i.hasNext()) { Map.Entry<K, V> entry = i.next(); if (entry.getKey().equals(key)) return entry.getValue(); } } return null; } public V put(K key, V value) { throw new UnsupportedOperationException(); } public V remove(Object key) { Iterator<Map.Entry<K, V>> i = entrySet().iterator(); while (i.hasNext()) { Map.Entry<K, V> entry = i.next(); if ((key == null && entry.getKey() == null) || (key != null && entry.getKey().equals(key))) { i.remove(); return entry.getValue(); } } return null; } public void putAll(Map<? extends K, ? extends V> map) { for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) put(entry.getKey(), entry.getValue()); } public void clear() { entrySet().clear(); } transient volatile Set<K> keySet = null; transient volatile Collection<V> values = null; public Set<K> keySet() { if (keySet == null) { keySet = new AbstractSet<K>() { @Override public Iterator<K> iterator() { return new Iterator<K>() { private Iterator<Map.Entry<K, V>> i = entrySet() .iterator(); @Override public boolean hasNext() { return i.hasNext(); } @Override public K next() { return i.next().getKey(); } @Override public void remove() { i.remove(); } }; } @Override public int size() { return AbstractMap.this.size(); } public boolean contains(Object key) { return AbstractMap.this.containsKey((K) key); } }; } return keySet; } public Collection<V> values() { if (values == null) { new AbstractCollection<V>() { @Override public Iterator<V> iterator() { return new Iterator<V>() { private Iterator<Map.Entry<K, V>> i = entrySet() .iterator(); @Override public boolean hasNext() { return i.hasNext(); } @Override public V next() { return i.next().getValue(); } @Override public void remove() { i.remove(); } }; } @Override public int size() { return AbstractMap.this.size(); } public boolean contains(Object obj) { return AbstractMap.this.containsValue((V) obj); } }; } return values; } public abstract Set<Map.Entry<K, V>> entrySet(); public boolean equals(Map<K, V> map) { if (map == this) return true; if (map.size() != size()) return false; Iterator<Map.Entry<K, V>> i = entrySet().iterator(); while (i.hasNext()) { Entry<K, V> entry = i.next(); K key = entry.getKey(); V value = entry.getValue(); if (!map.containsKey(key) || !map.containsValue(value)) return false; } return true; } public int hashCode() { int h = 0; Iterator<Map.Entry<K, V>> i = entrySet().iterator(); while (i.hasNext()) { h += i.next().hashCode(); } return h; } public String toString() { Iterator<Map.Entry<K, V>> i = entrySet().iterator(); if (!i.hasNext()) return "{}"; StringBuilder sb = new StringBuilder(); sb.append("{"); while (true) { Map.Entry<K, V> entry = i.next(); K key = entry.getKey(); V val = entry.getValue(); sb.append(key == this ? "(this map)" : key); sb.append("="); sb.append(val == this ? "(this map)" : val); if (!i.hasNext()) { return sb.append("}").toString(); } sb.append(", "); } } protected Object clone() throws CloneNotSupportedException { AbstractMap<K, V> result = (AbstractMap<K, V>) super.clone(); result.keySet = null; result.values = null; return result; } private static boolean eq(Object o1, Object o2) { return o1 == null ? o2 == null : o1.equals(o2); } public static class SimpleEntry<K, V> implements Map.Entry<K, V>, java.io.Serializable { private static final long serialVersionUID = -8499721149061103585L; private final K key; private V value; public SimpleEntry(K key, V value) { this.key = key; this.value = value; } public SimpleEntry(Map.Entry<? extends K, ? extends V> entry) { this.key = entry.getKey(); this.value = entry.getValue(); } @Override public K getKey() { return key; } @Override public V getValue() { return value; } @Override public V setValue(V val) { V oldValue = this.value; this.value = val; return oldValue; } @Override public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry entry = (Map.Entry) o; return eq(key, entry.getKey()) && eq(value, entry.getValue()); } @Override public int hashCode() { return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); } @Override public String toString() { return key + "=" + value; } } public static class SimpleImmutableEntry<K, V> implements Entry<K, V>, java.io.Serializable { private static final long serialVersionUID = 7138329143949025153L; private final K key; private final V value; public SimpleImmutableEntry(K key, V value) { this.key = key; this.value = value; } public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) { this.key = entry.getKey(); this.value = entry.getValue(); } public K getKey() { return key; } public V getValue() { return value; } public V setValue(V value) { throw new UnsupportedOperationException(); } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e = (Map.Entry) o; return eq(key, e.getKey()) && eq(value, e.getValue()); } public int hashCode() { return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); } public String toString() { return key + "=" + value; } } }
HashMap类
package util; import java.io.IOException; import java.util.AbstractCollection; import java.util.AbstractSet; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> { /** * 默认的初始化table容量 */ static final int DEFAULT_INITIAL_CAPACITY = 16; /** * 最大table容量 */ static final int MAXIMUM_CAPACITY = 1 << 30; /** * 默认负载系数 */ static final float DEFAULT_LOAD_FACTOR = 0.75f; /** * 实际存放HashMap数据的Entry数组 */ transient Entry[] table; /** * 当前HashMap元素个数(注意:不等与table.length) */ transient int size; /** * 阈值,当size超过threshold时,table将会扩容 * threshold = capacity * loadFactor */ int threshold; /** * 负载系数,作用见阈值 */ final float loadFactor; /** * Map元素的增删次数,作用是用来确定获取Iterator后 * 保证Map的元素不变,详见 HashIterator */ transient volatile int modCount; 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); int capacity = 1; // table容量只能为2的方幂 while (capacity < initialCapacity) capacity <<= 1; this.loadFactor = loadFactor; threshold = (int) (capacity * loadFactor); table = new Entry[capacity]; init(); } public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } public HashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); } public HashMap(Map<? extends K, ? extends V> map) { this(Math.max((int) (map.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); putAllForCreate(map); } void init() {} /** * 大名鼎鼎的hash算法,原来是这样的 * * @param h * @return */ static int hash(int h) { h ^= (h >>> 20 ) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } /** * 通过hash值确定元素在table中的下标 * * @param h * @param length * @return */ static int indexFor(int h, int length) { return h & (length - 1); } public int size() { return size; } public boolean isEmpty() { return size == 0; } /** * 通过key获取value,获取步骤: * 1. 通过key的hash值确定table下标 * 2. 遍历table下标对应的链表(这个链表就是解决冲突用的) * 3. 返回key值匹配的value */ public V get(K 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) { K k; if (e.hash == hash && ((k = e.key) == key || e.equals(k))) return e.value; } return null; } /** * 容易看出key为null的Entry存在table[0] * * @return */ private V getForNullKey() { for (Entry<K, V> e = table[0]; e != null; e = e.next) { if (e.key == null) return e.value; } return null; } public boolean containsKey(Object o) { return getEntry(o) != null; } /** * 与get()方法类似,只不过返回的是Entry * * @param key * @return */ final Entry<K, V> getEntry(Object key) { int hash = (key == null) ? 0 : hash(key.hashCode()); for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { K k; if ((e.hash == hash) && ((k = e.key) == key || (k != null && k.equals(key)))) return e; } return null; } /** * 插入方法,插入步骤为: * 1. 通过key的hash值确定table下标 * 2. 查找table下标的链表,如果key存在则更新对应的value * 3. 如果key不存在则调用addEntry()方法, 这种情况包括key冲突 */ public V put(K key, V val) { if (key == null) return putForNullKey(val); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry<K, V> e = table[i]; e != null; e = e.next) { if (e.hash == hash && (e.key == key || e.key.equals(key))) { V oldValue = e.value; e.value = val; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, val, i); return null; } /** * null值都插入table[0] * * @param value * @return */ private V putForNullKey(V value) { for (Entry<K, V> e = table[0]; e != null; e = e.next) { if (e.key == null){ V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(0, null, value, 0); return null; } /** * 类似与put()方法,区别在于没有返回值 * 以及不需要考虑modCount的变化 * * @param key * @param val */ private void putForCreate(K key, V val) { int hash = (key == null) ? 0 : hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry<K, V> e = table[i]; e != null; e = e.next) { if (hash == e.hash && (e.key == key || (e.key != null && e.key.equals(key)))) { e.value = val; return; } } createEntry(hash, key, val, i); } private void putAllForCreate(Map<? extends K, ? extends V> map) { for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = map.entrySet().iterator(); i.hasNext();) { Map.Entry<? extends K, ? extends V> entry = i.next(); putForCreate(entry.getKey(), entry.getValue()); } } /** * table扩容方法 * * @param newCapacity */ 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]; // 将所有旧table中的Entry复制到新的table transfer(newTable); table = newTable; threshold = (int) (newCapacity * loadFactor); } /** * 转移方法,将会重新计算所有Entry的下标 * * @param newTable */ void transfer(Entry[] newTable) { Entry[] src = table; int newCapacity = newTable.length; for (int i = 0; i < src.length; i++) { Entry<K, V> e = src[i]; if (e != null) { src[i] = null; do { Entry<K, V> next = e.next; int j = indexFor(e.hash, newCapacity); e.next = newTable[j]; newTable[j] = e; e = next; } while (e != null); } } } /** * 将参数map中所有Entry加入到当前map */ public void putAll(Map<? extends K, ? extends V> map) { int numKeysToBeAdded = map.size(); if (numKeysToBeAdded == 0) return; /** * 当 map.size() > threshold 时重新计算table容量 * 这里不选取 (table.length + map.size()) 作为新的容量是因为 * table与map中的Entry的key有可能存在重复,而造成table容量浪费 * 而如果使用 map.size() 作为阈值来计算新的容量,则最多只需要 * 在当 size > threshold 时调用put()的时候进行一次 2倍 扩容即可 */ if (numKeysToBeAdded > threshold) { int targetCapacity = (int) (numKeysToBeAdded / loadFactor + 1); if (targetCapacity > MAXIMUM_CAPACITY) targetCapacity = MAXIMUM_CAPACITY; int newCapacity = table.length; while (newCapacity < targetCapacity) newCapacity <<= 1; if (newCapacity > table.length) resize(newCapacity); } for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = entrySet().iterator(); i.hasNext();) { Map.Entry<? extends K, ? extends V> e = i.next(); put(e.getKey(), e.getValue()); } } /** * 通过 Key 来删除节点 */ public V remove(Object key) { Entry<K, V> e = removeEntryForKey(key); return e == null ? null : e.value; } final Entry<K, V> removeEntryForKey(Object key) { int hash = (key == null) ? 0 : hash(key.hashCode()); int i = indexFor(hash, table.length); Entry<K, V> prev = table[i]; for (Entry<K, V> e = table[i]; e != null; e = e.next) { if (e.hash == hash || (key == e.key || (e.key != null && e.key.equals(key)))) { modCount++; size--; // 注意此处删除链表节点的操作 if (e == prev) table[i] = e.next; else prev.next = prev.next.next; e.recordRemoval(this); return e; } prev = e; e = e.next; } return null; } /** * 通过 Entry 来删除节点 * * @param o * @return */ final Entry<K, V> removeMapping(Object o) { if (!(o instanceof Map.Entry)) return null; Map.Entry<K, V> entry = (Map.Entry<K, V>) o; K k = entry.getKey(); int hash = (k == null) ? 0 : hash(k.hashCode()); int i = indexFor(hash, table.length); Entry<K, V> prev = table[i]; for (Entry<K, V> e = table[i]; e != null; e = e.next) { if (e.hash == hash && e.equals(entry)) { modCount++; size--; if (e == prev) table[i] = e.next; else prev.next = e.next.next; e.recordRemoval(this); return e; } prev = e; e = e.next; } return null; } public void clear() { modCount++; for (int i = 0; i < table.length; i++) { table[i] = null; } size = 0; } public boolean containsValue(Object value) { if (value == null) containsNullValue(); for (int i = 0; i < table.length; i++) for (Entry<K, V> e = table[i]; e != null; e = e.next) if (value.equals(e.value)) return true; return false; } private boolean containsNullValue() { for (int i = 0; i < table.length; i++) for (Entry<K, V> e = table[i]; e != null; e = e.next) if (e.value == null) return true; return false; } public Object clone() { HashMap<K, V> result = null; try { result = (HashMap<K, V>) super.clone(); } catch (CloneNotSupportedException e) { // TODO: handle exception } result.table = new Entry[table.length]; result.entrySet = null; result.modCount = 0; result.size = 0; result.init(); result.putAllForCreate(this); return result; } /** * HashMap中真正存储元素的节点, * 也是冲突链表的链表节点 * * @author alexis * * @param <K> * @param <V> */ static class Entry<K, V> implements Map.Entry<K, V> { final K key; V value; final int hash; 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; } @Override public K getKey() { return key; } @Override public V getValue() { return value; } @Override public V setValue(V val) { V oldValue = value; value = val; return oldValue; } /** * 只有比较的Key和Value都相等才相等 */ @Override public final boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry<K, V> e = (Map.Entry<K, V>) o; K k1 = getKey(); K k2 = e.getKey(); if (k1 == k2 || (k1 != null && k1.equals(k2))) { V v1 = getValue(); V v2 = e.getValue(); if (v1 == v2 || (v1 != null && v1.equals(v2))) return true; } return false; } @Override public final int hashCode() { return ((key == null) ? 0 : key.hashCode()) ^ ((value == null) ? 0 : value.hashCode()); } @Override public final String toString() { return key + "=" + value; } void recordAccess(HashMap<K, V> map) {} void recordRemoval(HashMap<K, V> map) {} } /** * 添加新Entry,table扩容就在此处 * * @param hash * @param key * @param value * @param bucketIndex */ 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) resize(2 * table.length); } /** * 添加创建Map时的节点,不用考虑扩容问题 * * @param hash * @param key * @param value * @param bucketIndex */ void createEntry(int hash, K key, V value, int bucketIndex) { Entry<K, V> e = table[bucketIndex]; table[bucketIndex] = new Entry<K, V>(hash, key, value, e); size++; } /** * HashMap的遍历其,其特点有: * 1. 含有 expectedModCount,可防止获取Iterator后HashMap size发生变化 * 2. 由于hash算法的原因,Entry在table中是无序不规则存储,调用next时需要 * 自动跳过null元素 * * @author alexis * * @param <E> */ private abstract class HashIterator<E> implements Iterator<E> { Entry<K, V> next; int expectedModCount; int index; Entry<K, V> current; public HashIterator() { expectedModCount = modCount; if (size > 0) { Entry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } } public final boolean hasNext() { return next != null; } final Entry<K, V> nextEntry() { // 当获取Iterator后Map size发生变化,则会抛出异常 if (modCount != expectedModCount) throw new ConcurrentModificationException(); Entry<K, V> e = next; // 当已经不存在一下个元素时,抛出异常 if (e == null) throw new NoSuchElementException(); if ((next = e.next) == null) { Entry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } current = e; return e; } /** * 次方法用来删除next方法最后返回的那个元素 */ public void remove() { if (current == null) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); K k = current.key; current = null; HashMap.this.remove(k); expectedModCount = modCount; } } /** * 下面的各种 Iterator 就是重写了 next() 方法而已 * @author alexis * */ private final class ValueIterator extends HashIterator<V> { public V next() { return nextEntry().value; } } private final class KeyIterator extends HashIterator<K> { @Override public K next() { return nextEntry().key; } } private final class EntryIterator extends HashIterator<Map.Entry<K, V>> { @Override public Entry<K, V> next() { return nextEntry(); } } Iterator<K> newKeyIterator() { return new KeyIterator(); } Iterator<V> newValueIterator() { return new ValueIterator(); } Iterator<Map.Entry<K, V>> newEntryIterator() { return new EntryIterator(); } private transient Set<Map.Entry<K, V>> entrySet; public Set<K> keySet() { Set<K> ks = keySet; return (ks != null) ? ks : (keySet = new KeySet()); } private final class KeySet extends AbstractSet<K> { @Override public Iterator<K> iterator() { return newKeyIterator(); } @Override public int size() { return size; } public boolean contains(Object o) { return containsKey(o); } public boolean remove(Object o) { return HashMap.this.removeEntryForKey(o) != null; } public void clear() { HashMap.this.clear(); } } public Collection<V> values() { Collection<V> vs = values; return (vs != null) ? vs : (values = new Values()); } private final class Values extends AbstractCollection<V> { @Override public Iterator<V> iterator() { return new ValueIterator(); } @Override public int size() { return size; } public boolean contains(Object o) { return containsValue(o); } public void clear() { HashMap.this.clear(); } } public Set<Map.Entry<K, V>> entrySet() { return entrySet0(); } private Set<Map.Entry<K, V>> entrySet0() { Set<Map.Entry<K, V>> es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); } /** * 请注意 AbstractSet 是没有get()方法的, * 原因是 HashSet 是哈希存储,内部是乱序的, * 无法通过坐标获取值,其唯一的访问方法是通过Iterator * * @author alexis * */ private final class EntrySet extends AbstractSet<Map.Entry<K, V>> { @Override public Iterator<util.Map.Entry<K, V>> iterator() { return new EntryIterator(); } @Override public int size() { return size; } public boolean contains(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry<K, V> e = (Map.Entry<K, V>) o; Entry<K, V> candidate = getEntry(e.getKey()); return candidate != null && candidate.equals(e); } public boolean remove(Object o) { return removeMapping(o) != null; } public void clear() { HashMap.this.clear(); } } /** * 序列化与反序列化方法 * @param s * @throws IOException */ private void writeObject(java.io.ObjectOutputStream s) throws IOException { Iterator<Map.Entry<K, V>> i = (size > 0) ? entrySet0().iterator() : null; s.defaultWriteObject(); s.writeInt(table.length); s.writeInt(size); if (i != null) { while (i.hasNext()) { Map.Entry<K, V> e = i.next(); s.writeObject(e.getKey()); s.writeObject(e.getValue()); } } } private final static long serialVersionUID = 362498820763181265L; private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); int numBuckets = s.readInt(); table = new Entry[numBuckets]; init(); int size = s.readInt(); for (int i = 0; i < size; i++) { K key = (K) s.readObject(); V value = (V) s.readObject(); putForCreate(key, value); } } int capacity() { return table.length; } int loadFactor() { return loadFactor(); } }