zoukankan      html  css  js  c++  java
  • 详解Java HashMap

    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(); }
    }
  • 相关阅读:
    2019-07-08 L410 EST科技英语翻译
    L405 NYC-ATF4
    L403 Royal espionage
    L402 EST
    L401 哭声识别
    L400 How Trees Affect the Weather
    L398
    final, finally, finalize 的区别
    try {}里有一个 return 语句, 那么紧跟在这个 try 后的 finally {}里的 code会不会被执行,什么时候被执行,在 return 前还是后?
    下 面 这 条 语 句 一 共 创 建 了 多 少 个 对 象 : String s="a"+"b"+"c"+"d";
  • 原文地址:https://www.cnblogs.com/zemliu/p/2777993.html
Copyright © 2011-2022 走看看