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(); }
}
posted on 2012-11-19 21:06  ZimZz  阅读(2411)  评论(0编辑  收藏  举报