zoukankan      html  css  js  c++  java
  • 常用数据结构底层实现及源码

    ArrayList、HashMap、Collection、LinkedList、Redis 底层实现及源码

    Redis

    Redis简介

    Redis是一种key/value型数据库,其中,每个key和value都是使用对象表示的。

    SET message "Hello"
    

    其中,字符串 “message” 这个对象 就是 key , “Hello” 这个对象 就是 value

    Redis有5种对象的类型

    类型常量 小写 对象名称
    REDIS_STRING string 字符串对象
    REDIS_LIST list 列表对象
    REDIS_HASH hash 哈希对象
    REDIS_SET set 集合对象
    REDIS_ZSET zset 有序集合对象

    Redis对象底层数据结构

    编码常量 数据结构
    int long类型的整数
    embstr embstr编码的简单动态字符串
    raw 简单动态字符串
    ht 字典
    linkedlist 双端链表
    ziplist 压缩列表
    intset 整数集合
    skiplist 跳跃表和字典

    字符串对象

    字符串对象的编码可以是int、raw、embstr

    如果字符串对象的长度小于39字节,就用embstr

    否则用传统的raw对象

    # define REDIS_ENCODING_EMBSTR_SIZE_LIMIT 39  
    robj *createStringObject(char *ptr, size_t len) {  
        if (len <= REDIS_ENCODING_EMBSTR_SIZE_LIMIT)  
            return createEmbeddedStringObject(ptr,len);  
        else  
            return createRawStringObject(ptr,len);  
    }  
    

    embstr的优点:

    • 创建只需分配一次内存,raw为两次
    • 释放内存也是一次
    • embstr的objet和sds放在一起,更好地利用缓存带来的优势

    列表对象

    列表对象的编码可以是 ziplist or LinkedList

    ziplist 是一种压缩链表,好处是更能节省内存空间,存储的内容都是在连续的内存区域中的

    LinkedList是一种双向链表,没增加一个node,都要重新分配一个内存


    哈希对象

    哈希对象的底层实现用ziplist or hashtable

    ziplist : 对象数目不多且内容不大,这种方式效率很高

    HashTable由dict这个结构实现


    集合对象

    集合对象编码可以是 intset or HashTable


    有序集合对象

    编码一种是 ziplist ,一种是skipList 与 dict 的结合

    ziplist作为集合和作为哈希对象是一样的,member和score顺序存放。按照score从小到大顺序排列。它的结构不再复述。

    skiplist是一种跳跃表,它实现了有序集合中的快速查找,在大多数情况下它的速度都可以和平衡树差不多。但它的实现比较简单,可以作为平衡树的替代品。


    ArrayList

    ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长(1.5+1)。

    非线程安全

    源码:

    package java.util;    
       
    public class ArrayList<E> extends AbstractList<E>    
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable    
    {    
        // 序列版本号    
        private static final long serialVersionUID = 8683452581122892189L;    
       
        // ArrayList基于该数组实现,用该数组保存数据   
        private transient Object[] elementData;    
       
        // ArrayList中实际数据的数量    
        private int size;    
       
        // ArrayList带容量大小的构造函数。    
        public ArrayList(int initialCapacity) {    
            super();    
            if (initialCapacity < 0)    
                throw new IllegalArgumentException("Illegal Capacity: "+    
                                                   initialCapacity);    
            // 新建一个数组    
            this.elementData = new Object[initialCapacity];    
        }    
       
        // ArrayList无参构造函数。默认容量是10。    
        public ArrayList() {    
            this(10);    
        }    
       
        // 创建一个包含collection的ArrayList    
        public ArrayList(Collection<? extends E> c) {    
            elementData = c.toArray();    
            size = elementData.length;    
            if (elementData.getClass() != Object[].class)    
                elementData = Arrays.copyOf(elementData, size, Object[].class);    
        }    
       
       
        // 将当前容量值设为实际元素个数    
        public void trimToSize() {    
            modCount++;    
            int oldCapacity = elementData.length;    
            if (size < oldCapacity) {    
                elementData = Arrays.copyOf(elementData, size);    
            }    
        }    
       
       
        // 确定ArrarList的容量。    
        // 若ArrayList的容量不足以容纳当前的全部元素,设置 新的容量=“(原始容量x3)/2 + 1”    
        public void ensureCapacity(int minCapacity) {    
            // 将“修改统计数”+1,该变量主要是用来实现fail-fast机制的    
            modCount++;    
            int oldCapacity = elementData.length;    
            // 若当前容量不足以容纳当前的元素个数,设置 新的容量=“(原始容量x3)/2 + 1”    
            if (minCapacity > oldCapacity) {    
                Object oldData[] = elementData;    
                int newCapacity = (oldCapacity * 3)/2 + 1;    
                //如果还不够,则直接将minCapacity设置为当前容量  
                if (newCapacity < minCapacity)    
                    newCapacity = minCapacity;    
                elementData = Arrays.copyOf(elementData, newCapacity);    
            }    
        }    
       
        // 添加元素e    
        public boolean add(E e) {    
            // 确定ArrayList的容量大小    
            ensureCapacity(size + 1);  // Increments modCount!!    
            // 添加e到ArrayList中    
            elementData[size++] = e;    
            return true;    
        }    
       
        // 返回ArrayList的实际大小    
        public int size() {    
            return size;    
        }    
       
        // ArrayList是否包含Object(o)    
        public boolean contains(Object o) {    
            return indexOf(o) >= 0;    
        }    
       
        //返回ArrayList是否为空    
        public boolean isEmpty() {    
            return size == 0;    
        }    
       
        // 正向查找,返回元素的索引值    
        public int indexOf(Object o) {    
            if (o == null) {    
                for (int i = 0; i < size; i++)    
                if (elementData[i]==null)    
                    return i;    
                } else {    
                    for (int i = 0; i < size; i++)    
                    if (o.equals(elementData[i]))    
                        return i;    
                }    
                return -1;    
            }    
       
        // 反向查找(从数组末尾向开始查找),返回元素(o)的索引值    
        public int lastIndexOf(Object o) {    
            if (o == null) {    
                for (int i = size-1; i >= 0; i--)    
                if (elementData[i]==null)    
                    return i;    
            } else {    
                for (int i = size-1; i >= 0; i--)    
                if (o.equals(elementData[i]))    
                    return i;    
            }    
            return -1;    
        }    
         
       
        // 返回ArrayList的Object数组    
        public Object[] toArray() {    
            return Arrays.copyOf(elementData, size);    
        }    
       
        // 返回ArrayList元素组成的数组  
        public <T> T[] toArray(T[] a) {    
            // 若数组a的大小 < ArrayList的元素个数;    
            // 则新建一个T[]数组,数组大小是“ArrayList的元素个数”,并将“ArrayList”全部拷贝到新数组中    
            if (a.length < size)    
                return (T[]) Arrays.copyOf(elementData, size, a.getClass());    
       
            // 若数组a的大小 >= ArrayList的元素个数;    
            // 则将ArrayList的全部元素都拷贝到数组a中。    
            System.arraycopy(elementData, 0, a, 0, size);    
            if (a.length > size)    
                a[size] = null;    
            return a;    
        }    
       
        // 获取index位置的元素值    
        public E get(int index) {    
            RangeCheck(index);    
       
            return (E) elementData[index];    
        }    
       
        // 设置index位置的值为element    
        public E set(int index, E element) {    
            RangeCheck(index);    
       
            E oldValue = (E) elementData[index];    
            elementData[index] = element;    
            return oldValue;    
        }    
       
        // 将e添加到ArrayList中    
        public boolean add(E e) {    
            ensureCapacity(size + 1);  // Increments modCount!!    
            elementData[size++] = e;    
            return true;    
        }    
       
        // 将e添加到ArrayList的指定位置    
        public void add(int index, E element) {    
            if (index > size || index < 0)    
                throw new IndexOutOfBoundsException(    
                "Index: "+index+", Size: "+size);    
       
            ensureCapacity(size+1);  // Increments modCount!!    
            System.arraycopy(elementData, index, elementData, index + 1,    
                 size - index);    
            elementData[index] = element;    
            size++;    
        }    
       
        // 删除ArrayList指定位置的元素    
        public E remove(int index) {    
            RangeCheck(index);    
       
            modCount++;    
            E oldValue = (E) elementData[index];    
       
            int numMoved = size - index - 1;    
            if (numMoved > 0)    
                System.arraycopy(elementData, index+1, elementData, index,    
                     numMoved);    
            elementData[--size] = null; // Let gc do its work    
       
            return oldValue;    
        }    
       
        // 删除ArrayList的指定元素    
        public boolean remove(Object o) {    
            if (o == null) {    
                    for (int index = 0; index < size; index++)    
                if (elementData[index] == null) {    
                    fastRemove(index);    
                    return true;    
                }    
            } else {    
                for (int index = 0; index < size; index++)    
                if (o.equals(elementData[index])) {    
                    fastRemove(index);    
                    return true;    
                }    
            }    
            return false;    
        }    
       
       
        // 快速删除第index个元素    
        private void fastRemove(int index) {    
            modCount++;    
            int numMoved = size - index - 1;    
            // 从"index+1"开始,用后面的元素替换前面的元素。    
            if (numMoved > 0)    
                System.arraycopy(elementData, index+1, elementData, index,    
                                 numMoved);    
            // 将最后一个元素设为null    
            elementData[--size] = null; // Let gc do its work    
        }    
       
        // 删除元素    
        public boolean remove(Object o) {    
            if (o == null) {    
                for (int index = 0; index < size; index++)    
                if (elementData[index] == null) {    
                    fastRemove(index);    
                return true;    
                }    
            } else {    
                // 便利ArrayList,找到“元素o”,则删除,并返回true。    
                for (int index = 0; index < size; index++)    
                if (o.equals(elementData[index])) {    
                    fastRemove(index);    
                return true;    
                }    
            }    
            return false;    
        }    
       
        // 清空ArrayList,将全部的元素设为null    
        public void clear() {    
            modCount++;    
       
            for (int i = 0; i < size; i++)    
                elementData[i] = null;    
       
            size = 0;    
        }    
       
        // 将集合c追加到ArrayList中    
        public boolean addAll(Collection<? extends E> c) {    
            Object[] a = c.toArray();    
            int numNew = a.length;    
            ensureCapacity(size + numNew);  // Increments modCount    
            System.arraycopy(a, 0, elementData, size, numNew);    
            size += numNew;    
            return numNew != 0;    
        }    
       
        // 从index位置开始,将集合c添加到ArrayList    
        public boolean addAll(int index, Collection<? extends E> c) {    
            if (index > size || index < 0)    
                throw new IndexOutOfBoundsException(    
                "Index: " + index + ", Size: " + size);    
       
            Object[] a = c.toArray();    
            int numNew = a.length;    
            ensureCapacity(size + numNew);  // Increments modCount    
       
            int numMoved = size - index;    
            if (numMoved > 0)    
                System.arraycopy(elementData, index, elementData, index + numNew,    
                     numMoved);    
       
            System.arraycopy(a, 0, elementData, index, numNew);    
            size += numNew;    
            return numNew != 0;    
        }    
       
        // 删除fromIndex到toIndex之间的全部元素。    
        protected void removeRange(int fromIndex, int toIndex) {    
        modCount++;    
        int numMoved = size - toIndex;    
            System.arraycopy(elementData, toIndex, elementData, fromIndex,    
                             numMoved);    
       
        // Let gc do its work    
        int newSize = size - (toIndex-fromIndex);    
        while (size != newSize)    
            elementData[--size] = null;    
        }    
       
        private void RangeCheck(int index) {    
        if (index >= size)    
            throw new IndexOutOfBoundsException(    
            "Index: "+index+", Size: "+size);    
        }    
       
       
        // 克隆函数    
        public Object clone() {    
            try {    
                ArrayList<E> v = (ArrayList<E>) super.clone();    
                // 将当前ArrayList的全部元素拷贝到v中    
                v.elementData = Arrays.copyOf(elementData, size);    
                v.modCount = 0;    
                return v;    
            } catch (CloneNotSupportedException e) {    
                // this shouldn't happen, since we are Cloneable    
                throw new InternalError();    
            }    
        }    
       
       
        // java.io.Serializable的写入函数    
        // 将ArrayList的“容量,所有的元素值”都写入到输出流中    
        private void writeObject(java.io.ObjectOutputStream s)    
            throws java.io.IOException{    
        // Write out element count, and any hidden stuff    
        int expectedModCount = modCount;    
        s.defaultWriteObject();    
       
            // 写入“数组的容量”    
            s.writeInt(elementData.length);    
       
        // 写入“数组的每一个元素”    
        for (int i=0; i<size; i++)    
                s.writeObject(elementData[i]);    
       
        if (modCount != expectedModCount) {    
                throw new ConcurrentModificationException();    
            }    
       
        }    
       
       
        // java.io.Serializable的读取函数:根据写入方式读出    
        // 先将ArrayList的“容量”读出,然后将“所有的元素值”读出    
        private void readObject(java.io.ObjectInputStream s)    
            throws java.io.IOException, ClassNotFoundException {    
            // Read in size, and any hidden stuff    
            s.defaultReadObject();    
       
            // 从输入流中读取ArrayList的“容量”    
            int arrayLength = s.readInt();    
            Object[] a = elementData = new Object[arrayLength];    
       
            // 从输入流中将“所有的元素值”读出    
            for (int i=0; i<size; i++)    
                a[i] = s.readObject();    
        }    
    }  
    

    HashMap

    HashMap是基于哈希表实现,每一个元素都是一个key-value对,其内部通过单链表解决冲突问题,容量不足时,会自动增长。

    非线程安全,只是用于单线程环境下,多线程用concurrentHashMap

    实现了Serializable接口,因此支持序列化,实现了Cloneable接口,能被克隆。

    源码:

    package java.util;    
    import java.io.*;    
       
    public class HashMap<K,V>    
        extends AbstractMap<K,V>    
        implements Map<K,V>, Cloneable, Serializable    
    {    
       
        // 默认的初始容量(容量为HashMap中槽的数目)是16,且实际容量必须是2的整数次幂。    
        static final int DEFAULT_INITIAL_CAPACITY = 16;    
       
        // 最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换)    
        static final int MAXIMUM_CAPACITY = 1 << 30;    
       
        // 默认加载因子为0.75   
        static final float DEFAULT_LOAD_FACTOR = 0.75f;    
       
        // 存储数据的Entry数组,长度是2的幂。    
        // HashMap采用链表法解决冲突,每一个Entry本质上是一个单向链表    
        transient Entry[] table;    
       
        // HashMap的底层数组中已用槽的数量    
        transient int size;    
       
        // HashMap的阈值,用于判断是否需要调整HashMap的容量(threshold = 容量*加载因子)    
        int threshold;    
       
        // 加载因子实际大小    
        final float loadFactor;    
       
        // HashMap被改变的次数    
        transient volatile int modCount;    
       
        // 指定“容量大小”和“加载因子”的构造函数    
        public HashMap(int initialCapacity, float loadFactor) {    
            if (initialCapacity < 0)    
                throw new IllegalArgumentException("Illegal initial capacity: " +    
                                                   initialCapacity);    
            // HashMap的最大容量只能是MAXIMUM_CAPACITY    
            if (initialCapacity > MAXIMUM_CAPACITY)    
                initialCapacity = MAXIMUM_CAPACITY;    
            //加载因此不能小于0  
            if (loadFactor <= 0 || Float.isNaN(loadFactor))    
                throw new IllegalArgumentException("Illegal load factor: " +    
                                                   loadFactor);    
       
            // 找出“大于initialCapacity”的最小的2的幂    
            int capacity = 1;    
            while (capacity < initialCapacity)    
                capacity <<= 1;    
       
            // 设置“加载因子”    
            this.loadFactor = loadFactor;    
            // 设置“HashMap阈值”,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。    
            threshold = (int)(capacity * loadFactor);    
            // 创建Entry数组,用来保存数据    
            table = new Entry[capacity];    
            init();    
        }    
       
       
        // 指定“容量大小”的构造函数    
        public HashMap(int initialCapacity) {    
            this(initialCapacity, DEFAULT_LOAD_FACTOR);    
        }    
       
        // 默认构造函数。    
        public HashMap() {    
            // 设置“加载因子”为默认加载因子0.75    
            this.loadFactor = DEFAULT_LOAD_FACTOR;    
            // 设置“HashMap阈值”,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。    
            threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);    
            // 创建Entry数组,用来保存数据    
            table = new Entry[DEFAULT_INITIAL_CAPACITY];    
            init();    
        }    
       
        // 包含“子Map”的构造函数    
        public HashMap(Map<? extends K, ? extends V> m) {    
            this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,    
                          DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);    
            // 将m中的全部元素逐个添加到HashMap中    
            putAllForCreate(m);    
        }    
       
        //求hash值的方法,重新计算hash值  
        static int hash(int h) {    
            h ^= (h >>> 20) ^ (h >>> 12);    
            return h ^ (h >>> 7) ^ (h >>> 4);    
        }    
       
        // 返回h在数组中的索引值,这里用&代替取模,旨在提升效率   
        // h & (length-1)保证返回值的小于length    
        static int indexFor(int h, int length) {    
            return h & (length-1);    
        }    
       
        public int size() {    
            return size;    
        }    
       
        public boolean isEmpty() {    
            return size == 0;    
        }    
       
        // 获取key对应的value    
        public V get(Object key) {    
            if (key == null)    
                return getForNullKey();    
            // 获取key的hash值    
            int hash = hash(key.hashCode());    
            // 在“该hash值对应的链表”上查找“键值等于key”的元素    
            for (Entry<K,V> e = table[indexFor(hash, table.length)];    
                 e != null;    
                 e = e.next) {    
                Object k;    
                //判断key是否相同  
                if (e.hash == hash && ((k = e.key) == key || key.equals(k)))    
                    return e.value;    
            }  
            //没找到则返回null  
            return null;    
        }    
       
        // 获取“key为null”的元素的值    
        // HashMap将“key为null”的元素存储在table[0]位置,但不一定是该链表的第一个位置!    
        private V getForNullKey() {    
            for (Entry<K,V> e = table[0]; e != null; e = e.next) {    
                if (e.key == null)    
                    return e.value;    
            }    
            return null;    
        }    
       
        // HashMap是否包含key    
        public boolean containsKey(Object key) {    
            return getEntry(key) != null;    
        }    
       
        // 返回“键为key”的键值对    
        final Entry<K,V> getEntry(Object key) {    
            // 获取哈希值    
            // HashMap将“key为null”的元素存储在table[0]位置,“key不为null”的则调用hash()计算哈希值    
            int hash = (key == null) ? 0 : hash(key.hashCode());    
            // 在“该hash值对应的链表”上查找“键值等于key”的元素    
            for (Entry<K,V> e = table[indexFor(hash, table.length)];    
                 e != null;    
                 e = e.next) {    
                Object k;    
                if (e.hash == hash &&    
                    ((k = e.key) == key || (key != null && key.equals(k))))    
                    return e;    
            }    
            return null;    
        }    
       
        // 将“key-value”添加到HashMap中    
        public V put(K key, V value) {    
            // 若“key为null”,则将该键值对添加到table[0]中。    
            if (key == null)    
                return putForNullKey(value);    
            // 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。    
            int hash = hash(key.hashCode());    
            int i = indexFor(hash, table.length);    
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {    
                Object k;    
                // 若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!    
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {    
                    V oldValue = e.value;    
                    e.value = value;    
                    e.recordAccess(this);    
                    return oldValue;    
                }    
            }    
       
            // 若“该key”对应的键值对不存在,则将“key-value”添加到table中    
            modCount++;  
            //将key-value添加到table[i]处  
            addEntry(hash, key, value, i);    
            return null;    
        }    
       
        // putForNullKey()的作用是将“key为null”键值对添加到table[0]位置    
        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;    
                }    
            }    
            // 如果没有存在key为null的键值对,则直接题阿见到table[0]处!    
            modCount++;    
            addEntry(0, null, value, 0);    
            return null;    
        }    
       
        // 创建HashMap对应的“添加方法”,    
        // 它和put()不同。putForCreate()是内部方法,它被构造函数等调用,用来创建HashMap    
        // 而put()是对外提供的往HashMap中添加元素的方法。    
        private void putForCreate(K key, V value) {    
            int hash = (key == null) ? 0 : hash(key.hashCode());    
            int i = indexFor(hash, table.length);    
       
            // 若该HashMap表中存在“键值等于key”的元素,则替换该元素的value值    
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {    
                Object k;    
                if (e.hash == hash &&    
                    ((k = e.key) == key || (key != null && key.equals(k)))) {    
                    e.value = value;    
                    return;    
                }    
            }    
       
            // 若该HashMap表中不存在“键值等于key”的元素,则将该key-value添加到HashMap中    
            createEntry(hash, key, value, i);    
        }    
       
        // 将“m”中的全部元素都添加到HashMap中。    
        // 该方法被内部的构造HashMap的方法所调用。    
        private void putAllForCreate(Map<? extends K, ? extends V> m) {    
            // 利用迭代器将元素逐个添加到HashMap中    
            for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) {    
                Map.Entry<? extends K, ? extends V> e = i.next();    
                putForCreate(e.getKey(), e.getValue());    
            }    
        }    
       
        // 重新调整HashMap的大小,newCapacity是调整后的容量    
        void resize(int newCapacity) {    
            Entry[] oldTable = table;    
            int oldCapacity = oldTable.length;   
            //如果就容量已经达到了最大值,则不能再扩容,直接返回  
            if (oldCapacity == MAXIMUM_CAPACITY) {    
                threshold = Integer.MAX_VALUE;    
                return;    
            }    
       
            // 新建一个HashMap,将“旧HashMap”的全部元素添加到“新HashMap”中,    
            // 然后,将“新HashMap”赋值给“旧HashMap”。    
            Entry[] newTable = new Entry[newCapacity];    
            transfer(newTable);    
            table = newTable;    
            threshold = (int)(newCapacity * loadFactor);    
        }    
       
        // 将HashMap中的全部元素都添加到newTable中    
        void transfer(Entry[] newTable) {    
            Entry[] src = table;    
            int newCapacity = newTable.length;    
            for (int j = 0; j < src.length; j++) {    
                Entry<K,V> e = src[j];    
                if (e != null) {    
                    src[j] = null;    
                    do {    
                        Entry<K,V> next = e.next;    
                        int i = indexFor(e.hash, newCapacity);    
                        e.next = newTable[i];    
                        newTable[i] = e;    
                        e = next;    
                    } while (e != null);    
                }    
            }    
        }    
       
        // 将"m"的全部元素都添加到HashMap中    
        public void putAll(Map<? extends K, ? extends V> m) {    
            // 有效性判断    
            int numKeysToBeAdded = m.size();    
            if (numKeysToBeAdded == 0)    
                return;    
       
            // 计算容量是否足够,    
            // 若“当前阀值容量 < 需要的容量”,则将容量x2。    
            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);    
            }    
       
            // 通过迭代器,将“m”中的元素逐个添加到HashMap中。    
            for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.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);    
        }    
       
        // 删除“键为key”的元素    
        final Entry<K,V> removeEntryForKey(Object key) {    
            // 获取哈希值。若key为null,则哈希值为0;否则调用hash()进行计算    
            int hash = (key == null) ? 0 : hash(key.hashCode());    
            int i = indexFor(hash, table.length);    
            Entry<K,V> prev = table[i];    
            Entry<K,V> e = prev;    
       
            // 删除链表中“键为key”的元素    
            // 本质是“删除单向链表中的节点”    
            while (e != null) {    
                Entry<K,V> next = e.next;    
                Object k;    
                if (e.hash == hash &&    
                    ((k = e.key) == key || (key != null && key.equals(k)))) {    
                    modCount++;    
                    size--;    
                    if (prev == e)    
                        table[i] = next;    
                    else   
                        prev.next = next;    
                    e.recordRemoval(this);    
                    return e;    
                }    
                prev = e;    
                e = next;    
            }    
       
            return e;    
        }    
       
        // 删除“键值对”    
        final Entry<K,V> removeMapping(Object o) {    
            if (!(o instanceof Map.Entry))    
                return null;    
       
            Map.Entry<K,V> entry = (Map.Entry<K,V>) o;    
            Object key = entry.getKey();    
            int hash = (key == null) ? 0 : hash(key.hashCode());    
            int i = indexFor(hash, table.length);    
            Entry<K,V> prev = table[i];    
            Entry<K,V> e = prev;    
       
            // 删除链表中的“键值对e”    
            // 本质是“删除单向链表中的节点”    
            while (e != null) {    
                Entry<K,V> next = e.next;    
                if (e.hash == hash && e.equals(entry)) {    
                    modCount++;    
                    size--;    
                    if (prev == e)    
                        table[i] = next;    
                    else   
                        prev.next = next;    
                    e.recordRemoval(this);    
                    return e;    
                }    
                prev = e;    
                e = next;    
            }    
       
            return e;    
        }    
       
        // 清空HashMap,将所有的元素设为null    
        public void clear() {    
            modCount++;    
            Entry[] tab = table;    
            for (int i = 0; i < tab.length; i++)    
                tab[i] = null;    
            size = 0;    
        }    
       
        // 是否包含“值为value”的元素    
        public boolean containsValue(Object value) {    
        // 若“value为null”,则调用containsNullValue()查找    
        if (value == null)    
                return containsNullValue();    
       
        // 若“value不为null”,则查找HashMap中是否有值为value的节点。    
        Entry[] tab = table;    
            for (int i = 0; i < tab.length ; i++)    
                for (Entry e = tab[i] ; e != null ; e = e.next)    
                    if (value.equals(e.value))    
                        return true;    
        return false;    
        }    
       
        // 是否包含null值    
        private boolean containsNullValue() {    
        Entry[] tab = table;    
            for (int i = 0; i < tab.length ; i++)    
                for (Entry e = tab[i] ; e != null ; e = e.next)    
                    if (e.value == null)    
                        return true;    
        return false;    
        }    
       
        // 克隆一个HashMap,并返回Object对象    
        public Object clone() {    
            HashMap<K,V> result = null;    
            try {    
                result = (HashMap<K,V>)super.clone();    
            } catch (CloneNotSupportedException e) {    
                // assert false;    
            }    
            result.table = new Entry[table.length];    
            result.entrySet = null;    
            result.modCount = 0;    
            result.size = 0;    
            result.init();    
            // 调用putAllForCreate()将全部元素添加到HashMap中    
            result.putAllForCreate(this);    
       
            return result;    
        }    
       
        // Entry是单向链表。    
        // 它是 “HashMap链式存储法”对应的链表。    
        // 它实现了Map.Entry 接口,即实现getKey(), getValue(), setValue(V value), equals(Object o), hashCode()这些函数    
        static class Entry<K,V> implements Map.Entry<K,V> {    
            final K key;    
            V value;    
            // 指向下一个节点    
            Entry<K,V> next;    
            final int hash;    
       
            // 构造函数。    
            // 输入参数包括"哈希值(h)", "键(k)", "值(v)", "下一节点(n)"    
            Entry(int h, K k, V v, Entry<K,V> n) {    
                value = v;    
                next = n;    
                key = k;    
                hash = h;    
            }    
       
            public final K getKey() {    
                return key;    
            }    
       
            public final V getValue() {    
                return value;    
            }    
       
            public final V setValue(V newValue) {    
                V oldValue = value;    
                value = newValue;    
                return oldValue;    
            }    
       
            // 判断两个Entry是否相等    
            // 若两个Entry的“key”和“value”都相等,则返回true。    
            // 否则,返回false    
            public final boolean equals(Object o) {    
                if (!(o instanceof Map.Entry))    
                    return false;    
                Map.Entry e = (Map.Entry)o;    
                Object k1 = getKey();    
                Object k2 = e.getKey();    
                if (k1 == k2 || (k1 != null && k1.equals(k2))) {    
                    Object v1 = getValue();    
                    Object v2 = e.getValue();    
                    if (v1 == v2 || (v1 != null && v1.equals(v2)))    
                        return true;    
                }    
                return false;    
            }    
       
            // 实现hashCode()    
            public final int hashCode() {    
                return (key==null   ? 0 : key.hashCode()) ^    
                       (value==null ? 0 : value.hashCode());    
            }    
       
            public final String toString() {    
                return getKey() + "=" + getValue();    
            }    
       
            // 当向HashMap中添加元素时,绘调用recordAccess()。    
            // 这里不做任何处理    
            void recordAccess(HashMap<K,V> m) {    
            }    
       
            // 当从HashMap中删除元素时,绘调用recordRemoval()。    
            // 这里不做任何处理    
            void recordRemoval(HashMap<K,V> m) {    
            }    
        }    
       
        // 新增Entry。将“key-value”插入指定位置,bucketIndex是位置索引。    
        void addEntry(int hash, K key, V value, int bucketIndex) {    
            // 保存“bucketIndex”位置的值到“e”中    
            Entry<K,V> e = table[bucketIndex];    
            // 设置“bucketIndex”位置的元素为“新Entry”,    
            // 设置“e”为“新Entry的下一个节点”    
            table[bucketIndex] = new Entry<K,V>(hash, key, value, e);    
            // 若HashMap的实际大小 不小于 “阈值”,则调整HashMap的大小    
            if (size++ >= threshold)    
                resize(2 * table.length);    
        }    
       
        // 创建Entry。将“key-value”插入指定位置。    
        void createEntry(int hash, K key, V value, int bucketIndex) {    
            // 保存“bucketIndex”位置的值到“e”中    
            Entry<K,V> e = table[bucketIndex];    
            // 设置“bucketIndex”位置的元素为“新Entry”,    
            // 设置“e”为“新Entry的下一个节点”    
            table[bucketIndex] = new Entry<K,V>(hash, key, value, e);    
            size++;    
        }    
       
        // HashIterator是HashMap迭代器的抽象出来的父类,实现了公共了函数。    
        // 它包含“key迭代器(KeyIterator)”、“Value迭代器(ValueIterator)”和“Entry迭代器(EntryIterator)”3个子类。    
        private abstract class HashIterator<E> implements Iterator<E> {    
            // 下一个元素    
            Entry<K,V> next;    
            // expectedModCount用于实现fast-fail机制。    
            int expectedModCount;    
            // 当前索引    
            int index;    
            // 当前元素    
            Entry<K,V> current;    
       
            HashIterator() {    
                expectedModCount = modCount;    
                if (size > 0) { // advance to first entry    
                    Entry[] t = table;    
                    // 将next指向table中第一个不为null的元素。    
                    // 这里利用了index的初始值为0,从0开始依次向后遍历,直到找到不为null的元素就退出循环。    
                    while (index < t.length && (next = t[index++]) == null)    
                        ;    
                }    
            }    
       
            public final boolean hasNext() {    
                return next != null;    
            }    
       
            // 获取下一个元素    
            final Entry<K,V> nextEntry() {    
                if (modCount != expectedModCount)    
                    throw new ConcurrentModificationException();    
                Entry<K,V> e = next;    
                if (e == null)    
                    throw new NoSuchElementException();    
       
                // 注意!!!    
                // 一个Entry就是一个单向链表    
                // 若该Entry的下一个节点不为空,就将next指向下一个节点;    
                // 否则,将next指向下一个链表(也是下一个Entry)的不为null的节点。    
                if ((next = e.next) == null) {    
                    Entry[] t = table;    
                    while (index < t.length && (next = t[index++]) == null)    
                        ;    
                }    
                current = e;    
                return e;    
            }    
       
            // 删除当前元素    
            public void remove() {    
                if (current == null)    
                    throw new IllegalStateException();    
                if (modCount != expectedModCount)    
                    throw new ConcurrentModificationException();    
                Object k = current.key;    
                current = null;    
                HashMap.this.removeEntryForKey(k);    
                expectedModCount = modCount;    
            }    
       
        }    
       
        // value的迭代器    
        private final class ValueIterator extends HashIterator<V> {    
            public V next() {    
                return nextEntry().value;    
            }    
        }    
       
        // key的迭代器    
        private final class KeyIterator extends HashIterator<K> {    
            public K next() {    
                return nextEntry().getKey();    
            }    
        }    
       
        // Entry的迭代器    
        private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {    
            public Map.Entry<K,V> next() {    
                return nextEntry();    
            }    
        }    
       
        // 返回一个“key迭代器”    
        Iterator<K> newKeyIterator()   {    
            return new KeyIterator();    
        }    
        // 返回一个“value迭代器”    
        Iterator<V> newValueIterator()   {    
            return new ValueIterator();    
        }    
        // 返回一个“entry迭代器”    
        Iterator<Map.Entry<K,V>> newEntryIterator()   {    
            return new EntryIterator();    
        }    
       
        // HashMap的Entry对应的集合    
        private transient Set<Map.Entry<K,V>> entrySet = null;    
       
        // 返回“key的集合”,实际上返回一个“KeySet对象”    
        public Set<K> keySet() {    
            Set<K> ks = keySet;    
            return (ks != null ? ks : (keySet = new KeySet()));    
        }    
       
        // Key对应的集合    
        // KeySet继承于AbstractSet,说明该集合中没有重复的Key。    
        private final class KeySet extends AbstractSet<K> {    
            public Iterator<K> iterator() {    
                return newKeyIterator();    
            }    
            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();    
            }    
        }    
       
        // 返回“value集合”,实际上返回的是一个Values对象    
        public Collection<V> values() {    
            Collection<V> vs = values;    
            return (vs != null ? vs : (values = new Values()));    
        }    
       
        // “value集合”    
        // Values继承于AbstractCollection,不同于“KeySet继承于AbstractSet”,    
        // Values中的元素能够重复。因为不同的key可以指向相同的value。    
        private final class Values extends AbstractCollection<V> {    
            public Iterator<V> iterator() {    
                return newValueIterator();    
            }    
            public int size() {    
                return size;    
            }    
            public boolean contains(Object o) {    
                return containsValue(o);    
            }    
            public void clear() {    
                HashMap.this.clear();    
            }    
        }    
       
        // 返回“HashMap的Entry集合”    
        public Set<Map.Entry<K,V>> entrySet() {    
            return entrySet0();    
        }    
       
        // 返回“HashMap的Entry集合”,它实际是返回一个EntrySet对象    
        private Set<Map.Entry<K,V>> entrySet0() {    
            Set<Map.Entry<K,V>> es = entrySet;    
            return es != null ? es : (entrySet = new EntrySet());    
        }    
       
        // EntrySet对应的集合    
        // EntrySet继承于AbstractSet,说明该集合中没有重复的EntrySet。    
        private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {    
            public Iterator<Map.Entry<K,V>> iterator() {    
                return newEntryIterator();    
            }    
            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 int size() {    
                return size;    
            }    
            public void clear() {    
                HashMap.this.clear();    
            }    
        }    
       
        // java.io.Serializable的写入函数    
        // 将HashMap的“总的容量,实际容量,所有的Entry”都写入到输出流中    
        private void writeObject(java.io.ObjectOutputStream s)    
            throws IOException    
        {    
            Iterator<Map.Entry<K,V>> i =    
                (size > 0) ? entrySet0().iterator() : null;    
       
            // Write out the threshold, loadfactor, and any hidden stuff    
            s.defaultWriteObject();    
       
            // Write out number of buckets    
            s.writeInt(table.length);    
       
            // Write out size (number of Mappings)    
            s.writeInt(size);    
       
            // Write out keys and values (alternating)    
            if (i != null) {    
                while (i.hasNext()) {    
                Map.Entry<K,V> e = i.next();    
                s.writeObject(e.getKey());    
                s.writeObject(e.getValue());    
                }    
            }    
        }    
       
       
        private static final long serialVersionUID = 362498820763181265L;    
       
        // java.io.Serializable的读取函数:根据写入方式读出    
        // 将HashMap的“总的容量,实际容量,所有的Entry”依次读出    
        private void readObject(java.io.ObjectInputStream s)    
             throws IOException, ClassNotFoundException    
        {    
            // Read in the threshold, loadfactor, and any hidden stuff    
            s.defaultReadObject();    
       
            // Read in number of buckets and allocate the bucket array;    
            int numBuckets = s.readInt();    
            table = new Entry[numBuckets];    
       
            init();  // Give subclass a chance to do its thing.    
       
            // Read in size (number of Mappings)    
            int size = s.readInt();    
       
            // Read the keys and values, and put the mappings in the HashMap    
            for (int i=0; i<size; i++) {    
                K key = (K) s.readObject();    
                V value = (V) s.readObject();    
                putForCreate(key, value);    
            }    
        }    
       
        // 返回“HashMap总的容量”    
        int   capacity()     { return table.length; }    
        // 返回“HashMap的加载因子”    
        float loadFactor()   { return loadFactor;   }    
    }   
    

    HashTable

    基于哈希表实现,每个元素都是key-value对,内部通过单链表解决冲突问题,容量不足时,自动增长

    是线程安全的,能用于多线程

    实现了Serializable接口,支持序列号

    实现了Cloneable接口,能被克隆

    package java.util;    
    import java.io.*;    
       
    public class Hashtable<K,V>    
        extends Dictionary<K,V>    
        implements Map<K,V>, Cloneable, java.io.Serializable {    
       
        // 保存key-value的数组。    
        // Hashtable同样采用单链表解决冲突,每一个Entry本质上是一个单向链表    
        private transient Entry[] table;    
       
        // Hashtable中键值对的数量    
        private transient int count;    
       
        // 阈值,用于判断是否需要调整Hashtable的容量(threshold = 容量*加载因子)    
        private int threshold;    
       
        // 加载因子    
        private float loadFactor;    
       
        // Hashtable被改变的次数,用于fail-fast机制的实现    
        private transient int modCount = 0;    
       
        // 序列版本号    
        private static final long serialVersionUID = 1421746759512286392L;    
       
        // 指定“容量大小”和“加载因子”的构造函数    
        public Hashtable(int initialCapacity, float loadFactor) {    
            if (initialCapacity < 0)    
                throw new IllegalArgumentException("Illegal Capacity: "+    
                                                   initialCapacity);    
            if (loadFactor <= 0 || Float.isNaN(loadFactor))    
                throw new IllegalArgumentException("Illegal Load: "+loadFactor);    
       
            if (initialCapacity==0)    
                initialCapacity = 1;    
            this.loadFactor = loadFactor;    
            table = new Entry[initialCapacity];    
            threshold = (int)(initialCapacity * loadFactor);    
        }    
       
        // 指定“容量大小”的构造函数    
        public Hashtable(int initialCapacity) {    
            this(initialCapacity, 0.75f);    
        }    
       
        // 默认构造函数。    
        public Hashtable() {    
            // 默认构造函数,指定的容量大小是11;加载因子是0.75    
            this(11, 0.75f);    
        }    
       
        // 包含“子Map”的构造函数    
        public Hashtable(Map<? extends K, ? extends V> t) {    
            this(Math.max(2*t.size(), 11), 0.75f);    
            // 将“子Map”的全部元素都添加到Hashtable中    
            putAll(t);    
        }    
        
        private int hash(Object k) {
            if (useAltHashing) {
                if (k.getClass() == String.class) {
                    return sun.misc.Hashing.stringHash32((String) k);
                } else {
                    int h = hashSeed ^ k.hashCode();
    
                    // This function ensures that hashCodes that differ only by
                    // constant multiples at each bit position have a bounded
                    // number of collisions (approximately 8 at default load factor).
                    h ^= (h >>> 20) ^ (h >>> 12);
                    return h ^ (h >>> 7) ^ (h >>> 4);
                 }
            } else  {
                return k.hashCode();
            }
        }
       
        public synchronized int size() {    
            return count;    
        }    
       
        public synchronized boolean isEmpty() {    
            return count == 0;    
        }    
       
        // 返回“所有key”的枚举对象    
        public synchronized Enumeration<K> keys() {    
            return this.<K>getEnumeration(KEYS);    
        }    
       
        // 返回“所有value”的枚举对象    
        public synchronized Enumeration<V> elements() {    
            return this.<V>getEnumeration(VALUES);    
        }    
       
        // 判断Hashtable是否包含“值(value)”    
        public synchronized boolean contains(Object value) {    
            //注意,Hashtable中的value不能是null,    
            // 若是null的话,抛出异常!    
            if (value == null) {    
                throw new NullPointerException();    
            }    
       
            // 从后向前遍历table数组中的元素(Entry)    
            // 对于每个Entry(单向链表),逐个遍历,判断节点的值是否等于value    
            Entry tab[] = table;    
            for (int i = tab.length ; i-- > 0 ;) {    
                for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) {    
                    if (e.value.equals(value)) {    
                        return true;    
                    }    
                }    
            }    
            return false;    
        }    
       
        public boolean containsValue(Object value) {    
            return contains(value);    
        }    
       
        // 判断Hashtable是否包含key    
        public synchronized boolean containsKey(Object key) {    
            Entry tab[] = table;    
            //计算hash值,直接用key的hashCode代替  
            int hash = key.hashCode();      
            // 计算在数组中的索引值   
            int index = (hash & 0x7FFFFFFF) % tab.length;    
            // 找到“key对应的Entry(链表)”,然后在链表中找出“哈希值”和“键值”与key都相等的元素    
            for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {    
                if ((e.hash == hash) && e.key.equals(key)) {    
                    return true;    
                }    
            }    
            return false;    
        }    
       
        // 返回key对应的value,没有的话返回null    
        public synchronized V get(Object key) {    
            Entry tab[] = table;    
            int hash = hash(key);
            // 计算索引值,    
            int index = (hash & 0x7FFFFFFF) % tab.length;    
            // 找到“key对应的Entry(链表)”,然后在链表中找出“哈希值”和“键值”与key都相等的元素    
            for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {    
                if ((e.hash == hash) && e.key.equals(key)) {    
                    return e.value;    
                }    
            }    
            return null;    
        }    
       
        // 调整Hashtable的长度,将长度变成原来的2倍+1   
        protected void rehash() {    
            int oldCapacity = table.length;    
            Entry[] oldMap = table;    
       
            //创建新容量大小的Entry数组  
            int newCapacity = oldCapacity * 2 + 1;    
            Entry[] newMap = new Entry[newCapacity];    
       
            modCount++;    
            threshold = (int)(newCapacity * loadFactor);    
            table = newMap;    
              
            //将“旧的Hashtable”中的元素复制到“新的Hashtable”中  
            for (int i = oldCapacity ; i-- > 0 ;) {    
                for (Entry<K,V> old = oldMap[i] ; old != null ; ) {    
                    Entry<K,V> e = old;    
                    old = old.next;    
                    //重新计算index  
                    int index = (e.hash & 0x7FFFFFFF) % newCapacity;    
                    e.next = newMap[index];    
                    newMap[index] = e;    
                }    
            }    
        }    
       
        // 将“key-value”添加到Hashtable中    
        public synchronized V put(K key, V value) {    
            // Hashtable中不能插入value为null的元素!!!    
            if (value == null) {    
                throw new NullPointerException();    
            }    
       
            // 若“Hashtable中已存在键为key的键值对”,    
            // 则用“新的value”替换“旧的value”    
            Entry tab[] = table;    
            int hash = hash(key);
            int index = (hash & 0x7FFFFFFF) % tab.length;    
            for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {    
                if ((e.hash == hash) && e.key.equals(key)) {    
                    V old = e.value;    
                    e.value = value;    
                    return old;    
                    }    
            }    
       
            // 若“Hashtable中不存在键为key的键值对”,  
            // 将“修改统计数”+1    
            modCount++;    
            //  若“Hashtable实际容量” > “阈值”(阈值=总的容量 * 加载因子)    
            //  则调整Hashtable的大小    
            if (count >= threshold) {  
                rehash();    
       
                tab = table;    
                index = (hash & 0x7FFFFFFF) % tab.length;    
            }    
       
            //将新的key-value对插入到tab[index]处(即链表的头结点)  
            Entry<K,V> e = tab[index];           
            tab[index] = new Entry<K,V>(hash, key, value, e);    
            count++;    
            return null;    
        }    
       
        // 删除Hashtable中键为key的元素    
        public synchronized V remove(Object key) {    
            Entry tab[] = table;    
            int hash = hash(key);
            int index = (hash & 0x7FFFFFFF) % tab.length;    
              
            //从table[index]链表中找出要删除的节点,并删除该节点。  
            //因为是单链表,因此要保留带删节点的前一个节点,才能有效地删除节点  
            for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {    
                if ((e.hash == hash) && e.key.equals(key)) {    
                    modCount++;    
                    if (prev != null) {    
                        prev.next = e.next;    
                    } else {    
                        tab[index] = e.next;    
                    }    
                    count--;    
                    V oldValue = e.value;    
                    e.value = null;    
                    return oldValue;    
                }    
            }    
            return null;    
        }    
       
        // 将“Map(t)”的中全部元素逐一添加到Hashtable中    
        public synchronized void putAll(Map<? extends K, ? extends V> t) {    
            for (Map.Entry<? extends K, ? extends V> e : t.entrySet())    
                put(e.getKey(), e.getValue());    
        }    
       
        // 清空Hashtable    
        // 将Hashtable的table数组的值全部设为null    
        public synchronized void clear() {    
            Entry tab[] = table;    
            modCount++;    
            for (int index = tab.length; --index >= 0; )    
                tab[index] = null;    
            count = 0;    
        }    
       
        // 克隆一个Hashtable,并以Object的形式返回。    
        public synchronized Object clone() {    
            try {    
                Hashtable<K,V> t = (Hashtable<K,V>) super.clone();    
                t.table = new Entry[table.length];    
                for (int i = table.length ; i-- > 0 ; ) {    
                    t.table[i] = (table[i] != null)    
                    ? (Entry<K,V>) table[i].clone() : null;    
                }    
                t.keySet = null;    
                t.entrySet = null;    
                t.values = null;    
                t.modCount = 0;    
                return t;    
            } catch (CloneNotSupportedException e) {     
                throw new InternalError();    
            }    
        }    
       
        public synchronized String toString() {    
            int max = size() - 1;    
            if (max == -1)    
                return "{}";    
       
            StringBuilder sb = new StringBuilder();    
            Iterator<Map.Entry<K,V>> it = entrySet().iterator();    
       
            sb.append('{');    
            for (int i = 0; ; i++) {    
                Map.Entry<K,V> e = it.next();    
                K key = e.getKey();    
                V value = e.getValue();    
                sb.append(key   == this ? "(this Map)" : key.toString());    
                sb.append('=');    
                sb.append(value == this ? "(this Map)" : value.toString());    
       
                if (i == max)    
                    return sb.append('}').toString();    
                sb.append(", ");    
            }    
        }    
       
        // 获取Hashtable的枚举类对象    
        // 若Hashtable的实际大小为0,则返回“空枚举类”对象;    
        // 否则,返回正常的Enumerator的对象。   
        private <T> Enumeration<T> getEnumeration(int type) {    
        if (count == 0) {    
            return (Enumeration<T>)emptyEnumerator;    
        } else {    
            return new Enumerator<T>(type, false);    
        }    
        }    
       
        // 获取Hashtable的迭代器    
        // 若Hashtable的实际大小为0,则返回“空迭代器”对象;    
        // 否则,返回正常的Enumerator的对象。(Enumerator实现了迭代器和枚举两个接口)    
        private <T> Iterator<T> getIterator(int type) {    
            if (count == 0) {    
                return (Iterator<T>) emptyIterator;    
            } else {    
                return new Enumerator<T>(type, true);    
            }    
        }    
       
        // Hashtable的“key的集合”。它是一个Set,没有重复元素    
        private transient volatile Set<K> keySet = null;    
        // Hashtable的“key-value的集合”。它是一个Set,没有重复元素    
        private transient volatile Set<Map.Entry<K,V>> entrySet = null;    
        // Hashtable的“key-value的集合”。它是一个Collection,可以有重复元素    
        private transient volatile Collection<V> values = null;    
       
        // 返回一个被synchronizedSet封装后的KeySet对象    
        // synchronizedSet封装的目的是对KeySet的所有方法都添加synchronized,实现多线程同步    
        public Set<K> keySet() {    
            if (keySet == null)    
                keySet = Collections.synchronizedSet(new KeySet(), this);    
            return keySet;    
        }    
       
        // Hashtable的Key的Set集合。    
        // KeySet继承于AbstractSet,所以,KeySet中的元素没有重复的。    
        private class KeySet extends AbstractSet<K> {    
            public Iterator<K> iterator() {    
                return getIterator(KEYS);    
            }    
            public int size() {    
                return count;    
            }    
            public boolean contains(Object o) {    
                return containsKey(o);    
            }    
            public boolean remove(Object o) {    
                return Hashtable.this.remove(o) != null;    
            }    
            public void clear() {    
                Hashtable.this.clear();    
            }    
        }    
       
        // 返回一个被synchronizedSet封装后的EntrySet对象    
        // synchronizedSet封装的目的是对EntrySet的所有方法都添加synchronized,实现多线程同步    
        public Set<Map.Entry<K,V>> entrySet() {    
            if (entrySet==null)    
                entrySet = Collections.synchronizedSet(new EntrySet(), this);    
            return entrySet;    
        }    
       
        // Hashtable的Entry的Set集合。    
        // EntrySet继承于AbstractSet,所以,EntrySet中的元素没有重复的。    
        private class EntrySet extends AbstractSet<Map.Entry<K,V>> {    
            public Iterator<Map.Entry<K,V>> iterator() {    
                return getIterator(ENTRIES);    
            }    
       
            public boolean add(Map.Entry<K,V> o) {    
                return super.add(o);    
            }    
       
            // 查找EntrySet中是否包含Object(0)    
            // 首先,在table中找到o对应的Entry链表    
            // 然后,查找Entry链表中是否存在Object    
            public boolean contains(Object o) {    
                if (!(o instanceof Map.Entry))    
                    return false;    
                Map.Entry entry = (Map.Entry)o;    
                Object key = entry.getKey();    
                Entry[] tab = table;    
                int hash = hash(key);
                int index = (hash & 0x7FFFFFFF) % tab.length;    
       
                for (Entry e = tab[index]; e != null; e = e.next)    
                    if (e.hash==hash && e.equals(entry))    
                        return true;    
                return false;    
            }    
       
            // 删除元素Object(0)    
            // 首先,在table中找到o对应的Entry链表  
            // 然后,删除链表中的元素Object    
            public boolean remove(Object o) {    
                if (!(o instanceof Map.Entry))    
                    return false;    
                Map.Entry<K,V> entry = (Map.Entry<K,V>) o;    
                K key = entry.getKey();    
                Entry[] tab = table;    
                int hash = hash(key);
                int index = (hash & 0x7FFFFFFF) % tab.length;    
       
                for (Entry<K,V> e = tab[index], prev = null; e != null;    
                     prev = e, e = e.next) {    
                    if (e.hash==hash && e.equals(entry)) {    
                        modCount++;    
                        if (prev != null)    
                            prev.next = e.next;    
                        else   
                            tab[index] = e.next;    
       
                        count--;    
                        e.value = null;    
                        return true;    
                    }    
                }    
                return false;    
            }    
       
            public int size() {    
                return count;    
            }    
       
            public void clear() {    
                Hashtable.this.clear();    
            }    
        }    
       
        // 返回一个被synchronizedCollection封装后的ValueCollection对象    
        // synchronizedCollection封装的目的是对ValueCollection的所有方法都添加synchronized,实现多线程同步    
        public Collection<V> values() {    
        if (values==null)    
            values = Collections.synchronizedCollection(new ValueCollection(),    
                                                            this);    
            return values;    
        }    
       
        // Hashtable的value的Collection集合。    
        // ValueCollection继承于AbstractCollection,所以,ValueCollection中的元素可以重复的。    
        private class ValueCollection extends AbstractCollection<V> {    
            public Iterator<V> iterator() {    
            return getIterator(VALUES);    
            }    
            public int size() {    
                return count;    
            }    
            public boolean contains(Object o) {    
                return containsValue(o);    
            }    
            public void clear() {    
                Hashtable.this.clear();    
            }    
        }    
       
        // 重新equals()函数    
        // 若两个Hashtable的所有key-value键值对都相等,则判断它们两个相等    
        public synchronized boolean equals(Object o) {    
            if (o == this)    
                return true;    
       
            if (!(o instanceof Map))    
                return false;    
            Map<K,V> t = (Map<K,V>) o;    
            if (t.size() != size())    
                return false;    
       
            try {    
                // 通过迭代器依次取出当前Hashtable的key-value键值对    
                // 并判断该键值对,存在于Hashtable中。    
                // 若不存在,则立即返回false;否则,遍历完“当前Hashtable”并返回true。    
                Iterator<Map.Entry<K,V>> i = entrySet().iterator();    
                while (i.hasNext()) {    
                    Map.Entry<K,V> e = i.next();    
                    K key = e.getKey();    
                    V value = e.getValue();    
                    if (value == null) {    
                        if (!(t.get(key)==null && t.containsKey(key)))    
                            return false;    
                    } else {    
                        if (!value.equals(t.get(key)))    
                            return false;    
                    }    
                }    
            } catch (ClassCastException unused)   {    
                return false;    
            } catch (NullPointerException unused) {    
                return false;    
            }    
       
            return true;    
        }    
       
        // 计算Entry的hashCode    
        // 若 Hashtable的实际大小为0 或者 加载因子<0,则返回0。    
        // 否则,返回“Hashtable中的每个Entry的key和value的异或值 的总和”。    
        public synchronized int hashCode() {    
            int h = 0;    
            if (count == 0 || loadFactor < 0)    
                return h;  // Returns zero    
       
            loadFactor = -loadFactor;  // Mark hashCode computation in progress    
            Entry[] tab = table;    
            for (int i = 0; i < tab.length; i++)    
                for (Entry e = tab[i]; e != null; e = e.next)    
                    h += e.key.hashCode() ^ e.value.hashCode();    
            loadFactor = -loadFactor;  // Mark hashCode computation complete    
       
            return h;    
        }    
       
        // java.io.Serializable的写入函数    
        // 将Hashtable的“总的容量,实际容量,所有的Entry”都写入到输出流中    
        private synchronized void writeObject(java.io.ObjectOutputStream s)    
            throws IOException    
        {    
            // Write out the length, threshold, loadfactor    
            s.defaultWriteObject();    
       
            // Write out length, count of elements and then the key/value objects    
            s.writeInt(table.length);    
            s.writeInt(count);    
            for (int index = table.length-1; index >= 0; index--) {    
                Entry entry = table[index];    
       
                while (entry != null) {    
                s.writeObject(entry.key);    
                s.writeObject(entry.value);    
                entry = entry.next;    
                }    
            }    
        }    
       
        // java.io.Serializable的读取函数:根据写入方式读出    
        // 将Hashtable的“总的容量,实际容量,所有的Entry”依次读出    
        private void readObject(java.io.ObjectInputStream s)    
             throws IOException, ClassNotFoundException    
        {    
            // Read in the length, threshold, and loadfactor    
            s.defaultReadObject();    
       
            // Read the original length of the array and number of elements    
            int origlength = s.readInt();    
            int elements = s.readInt();    
       
            // Compute new size with a bit of room 5% to grow but    
            // no larger than the original size.  Make the length    
            // odd if it's large enough, this helps distribute the entries.    
            // Guard against the length ending up zero, that's not valid.    
            int length = (int)(elements * loadFactor) + (elements / 20) + 3;    
            if (length > elements && (length & 1) == 0)    
                length--;    
            if (origlength > 0 && length > origlength)    
                length = origlength;    
       
            Entry[] table = new Entry[length];    
            count = 0;    
       
            // Read the number of elements and then all the key/value objects    
            for (; elements > 0; elements--) {    
                K key = (K)s.readObject();    
                V value = (V)s.readObject();    
                    // synch could be eliminated for performance    
                    reconstitutionPut(table, key, value);    
            }    
            this.table = table;    
        }    
       
        private void reconstitutionPut(Entry[] tab, K key, V value)    
            throws StreamCorruptedException    
        {    
            if (value == null) {    
                throw new java.io.StreamCorruptedException();    
            }    
            // Makes sure the key is not already in the hashtable.    
            // This should not happen in deserialized version.    
            int hash = key.hashCode();    
            int index = (hash & 0x7FFFFFFF) % tab.length;    
            for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {    
                if ((e.hash == hash) && e.key.equals(key)) {    
                    throw new java.io.StreamCorruptedException();    
                }    
            }    
            // Creates the new entry.    
            Entry<K,V> e = tab[index];    
            tab[index] = new Entry<K,V>(hash, key, value, e);    
            count++;    
        }    
       
        // Hashtable的Entry节点,它本质上是一个单向链表。    
        // 也因此,我们才能推断出Hashtable是由拉链法实现的散列表    
        private static class Entry<K,V> implements Map.Entry<K,V> {    
            // 哈希值    
            int hash;    
            K key;    
            V value;    
            // 指向的下一个Entry,即链表的下一个节点    
            Entry<K,V> next;    
       
            // 构造函数    
            protected Entry(int hash, K key, V value, Entry<K,V> next) {    
                this.hash = hash;    
                this.key = key;    
                this.value = value;    
                this.next = next;    
            }    
       
            protected Object clone() {    
                return new Entry<K,V>(hash, key, value,    
                      (next==null ? null : (Entry<K,V>) next.clone()));    
            }    
       
            public K getKey() {    
                return key;    
            }    
       
            public V getValue() {    
                return value;    
            }    
       
            // 设置value。若value是null,则抛出异常。    
            public V setValue(V value) {    
                if (value == null)    
                    throw new NullPointerException();    
       
                V oldValue = this.value;    
                this.value = value;    
                return oldValue;    
            }    
       
            // 覆盖equals()方法,判断两个Entry是否相等。    
            // 若两个Entry的key和value都相等,则认为它们相等。    
            public boolean equals(Object o) {    
                if (!(o instanceof Map.Entry))    
                    return false;    
                Map.Entry e = (Map.Entry)o;    
       
                return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&    
                   (value==null ? e.getValue()==null : value.equals(e.getValue()));    
            }    
       
            public int hashCode() {    
                return hash ^ (value==null ? 0 : value.hashCode());    
            }    
       
            public String toString() {    
                return key.toString()+"="+value.toString();    
            }    
        }    
       
        private static final int KEYS = 0;    
        private static final int VALUES = 1;    
        private static final int ENTRIES = 2;    
       
        // Enumerator的作用是提供了“通过elements()遍历Hashtable的接口” 和 “通过entrySet()遍历Hashtable的接口”。    
        private class Enumerator<T> implements Enumeration<T>, Iterator<T> {    
            // 指向Hashtable的table    
            Entry[] table = Hashtable.this.table;    
            // Hashtable的总的大小    
            int index = table.length;    
            Entry<K,V> entry = null;    
            Entry<K,V> lastReturned = null;    
            int type;    
       
            // Enumerator是 “迭代器(Iterator)” 还是 “枚举类(Enumeration)”的标志    
            // iterator为true,表示它是迭代器;否则,是枚举类。    
            boolean iterator;    
       
            // 在将Enumerator当作迭代器使用时会用到,用来实现fail-fast机制。    
            protected int expectedModCount = modCount;    
       
            Enumerator(int type, boolean iterator) {    
                this.type = type;    
                this.iterator = iterator;    
            }    
       
            // 从遍历table的数组的末尾向前查找,直到找到不为null的Entry。    
            public boolean hasMoreElements() {    
                Entry<K,V> e = entry;    
                int i = index;    
                Entry[] t = table;    
                /* Use locals for faster loop iteration */   
                while (e == null && i > 0) {    
                    e = t[--i];    
                }    
                entry = e;    
                index = i;    
                return e != null;    
            }    
       
            // 获取下一个元素    
            // 注意:从hasMoreElements() 和nextElement() 可以看出“Hashtable的elements()遍历方式”    
            // 首先,从后向前的遍历table数组。table数组的每个节点都是一个单向链表(Entry)。    
            // 然后,依次向后遍历单向链表Entry。    
            public T nextElement() {    
                Entry<K,V> et = entry;    
                int i = index;    
                Entry[] t = table;    
                /* Use locals for faster loop iteration */   
                while (et == null && i > 0) {    
                    et = t[--i];    
                }    
                entry = et;    
                index = i;    
                if (et != null) {    
                    Entry<K,V> e = lastReturned = entry;    
                    entry = e.next;    
                    return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);    
                }    
                throw new NoSuchElementException("Hashtable Enumerator");    
            }    
       
            // 迭代器Iterator的判断是否存在下一个元素    
            // 实际上,它是调用的hasMoreElements()    
            public boolean hasNext() {    
                return hasMoreElements();    
            }    
       
            // 迭代器获取下一个元素    
            // 实际上,它是调用的nextElement()    
            public T next() {    
                if (modCount != expectedModCount)    
                    throw new ConcurrentModificationException();    
                return nextElement();    
            }    
       
            // 迭代器的remove()接口。    
            // 首先,它在table数组中找出要删除元素所在的Entry,    
            // 然后,删除单向链表Entry中的元素。    
            public void remove() {    
                if (!iterator)    
                    throw new UnsupportedOperationException();    
                if (lastReturned == null)    
                    throw new IllegalStateException("Hashtable Enumerator");    
                if (modCount != expectedModCount)    
                    throw new ConcurrentModificationException();    
       
                synchronized(Hashtable.this) {    
                    Entry[] tab = Hashtable.this.table;    
                    int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;    
       
                    for (Entry<K,V> e = tab[index], prev = null; e != null;    
                         prev = e, e = e.next) {    
                        if (e == lastReturned) {    
                            modCount++;    
                            expectedModCount++;    
                            if (prev == null)    
                                tab[index] = e.next;    
                            else   
                                prev.next = e.next;    
                            count--;    
                            lastReturned = null;    
                            return;    
                        }    
                    }    
                    throw new ConcurrentModificationException();    
                }    
            }    
        }    
       
       
        private static Enumeration emptyEnumerator = new EmptyEnumerator();    
        private static Iterator emptyIterator = new EmptyIterator();    
       
        // 空枚举类    
        // 当Hashtable的实际大小为0;此时,又要通过Enumeration遍历Hashtable时,返回的是“空枚举类”的对象。    
        private static class EmptyEnumerator implements Enumeration<Object> {    
       
            EmptyEnumerator() {    
            }    
       
            // 空枚举类的hasMoreElements() 始终返回false    
            public boolean hasMoreElements() {    
                return false;    
            }    
       
            // 空枚举类的nextElement() 抛出异常    
            public Object nextElement() {    
                throw new NoSuchElementException("Hashtable Enumerator");    
            }    
        }    
       
       
        // 空迭代器    
        // 当Hashtable的实际大小为0;此时,又要通过迭代器遍历Hashtable时,返回的是“空迭代器”的对象。    
        private static class EmptyIterator implements Iterator<Object> {    
       
            EmptyIterator() {    
            }    
       
            public boolean hasNext() {    
                return false;    
            }    
       
            public Object next() {    
                throw new NoSuchElementException("Hashtable Iterator");    
            }    
       
            public void remove() {    
                throw new IllegalStateException("Hashtable Iterator");    
            }    
       
        }    
    }   
    

    Collection

    是最基本的集合接口

    继承的接口:Iterable

    子接口:List、Set、Queue等

    遍历Collection中的每一个元素

    它支持一个Iterator()方法,该方法返回一个迭代子,该迭代子可逐一访问Collection中每一个元素

    Iterator it = collection.iterator(); // 获得一个迭代子
        while(it.hasNext())  
        {
            Object obj = it.next(); // 得到下一个元素
        }
    

    方法:

    retainAll(Collection<?extends E>c);  //保留,交运算
    addAll(Collection<?extends E>c);       //添加,并运算
    removeAll(Collection<?extends E>c);     //移除,减运算
    

    LinkedList

    LinkedList是基于双向循环链表实现的,除了可以当作链表来操作外,它还可以当作栈、队列和双端队列来使用。

    非线程安全,单线程下使用

    LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了Cloneable接口,能被克隆。

    • 是一个类
    • 实现的接口:List、Collection、Iterable、Serializable、Cloneable、Deque,Queue
    • 子类:没有子类

    添加元素方法:

    boolean add(E e) 添加到链表末尾

    void add(int index, E e) 添加到指定位置

    boolean addAll(int index, Collection<? extends E> c)

    boolean addAll(Collection<? extends E> c)

    package java.util;    
       
    public class LinkedList<E>    
        extends AbstractSequentialList<E>    
        implements List<E>, Deque<E>, Cloneable, java.io.Serializable    
    {    
        // 链表的表头,表头不包含任何数据。Entry是个链表类数据结构。    
        private transient Entry<E> header = new Entry<E>(null, null, null);    
       
        // LinkedList中元素个数    
        private transient int size = 0;    
       
        // 默认构造函数:创建一个空的链表    
        public LinkedList() {    
            header.next = header.previous = header;    
        }    
       
        // 包含“集合”的构造函数:创建一个包含“集合”的LinkedList    
        public LinkedList(Collection<? extends E> c) {    
            this();    
            addAll(c);    
        }    
       
        // 获取LinkedList的第一个元素    
        public E getFirst() {    
            if (size==0)    
                throw new NoSuchElementException();    
       
            // 链表的表头header中不包含数据。    
            // 这里返回header所指下一个节点所包含的数据。    
            return header.next.element;    
        }    
       
        // 获取LinkedList的最后一个元素    
        public E getLast()  {    
            if (size==0)    
                throw new NoSuchElementException();    
       
            // 由于LinkedList是双向链表;而表头header不包含数据。    
            // 因而,这里返回表头header的前一个节点所包含的数据。    
            return header.previous.element;    
        }    
       
        // 删除LinkedList的第一个元素    
        public E removeFirst() {    
            return remove(header.next);    
        }    
       
        // 删除LinkedList的最后一个元素    
        public E removeLast() {    
            return remove(header.previous);    
        }    
       
        // 将元素添加到LinkedList的起始位置    
        public void addFirst(E e) {    
            addBefore(e, header.next);    
        }    
       
        // 将元素添加到LinkedList的结束位置    
        public void addLast(E e) {    
            addBefore(e, header);    
        }    
       
        // 判断LinkedList是否包含元素(o)    
        public boolean contains(Object o) {    
            return indexOf(o) != -1;    
        }    
       
        // 返回LinkedList的大小    
        public int size() {    
            return size;    
        }    
       
        // 将元素(E)添加到LinkedList中    
        public boolean add(E e) {    
            // 将节点(节点数据是e)添加到表头(header)之前。    
            // 即,将节点添加到双向链表的末端。    
            addBefore(e, header);    
            return true;    
        }    
       
        // 从LinkedList中删除元素(o)    
        // 从链表开始查找,如存在元素(o)则删除该元素并返回true;    
        // 否则,返回false。    
        public boolean remove(Object o) {    
            if (o==null) {    
                // 若o为null的删除情况    
                for (Entry<E> e = header.next; e != header; e = e.next) {    
                    if (e.element==null) {    
                        remove(e);    
                        return true;    
                    }    
                }    
            } else {    
                // 若o不为null的删除情况    
                for (Entry<E> e = header.next; e != header; e = e.next) {    
                    if (o.equals(e.element)) {    
                        remove(e);    
                        return true;    
                    }    
                }    
            }    
            return false;    
        }    
       
        // 将“集合(c)”添加到LinkedList中。    
        // 实际上,是从双向链表的末尾开始,将“集合(c)”添加到双向链表中。    
        public boolean addAll(Collection<? extends E> c) {    
            return addAll(size, c);    
        }    
       
        // 从双向链表的index开始,将“集合(c)”添加到双向链表中。    
        public boolean addAll(int index, Collection<? extends E> c) {    
            if (index < 0 || index > size)    
                throw new IndexOutOfBoundsException("Index: "+index+    
                                                    ", Size: "+size);    
            Object[] a = c.toArray();    
            // 获取集合的长度    
            int numNew = a.length;    
            if (numNew==0)    
                return false;    
            modCount++;    
       
            // 设置“当前要插入节点的后一个节点”    
            Entry<E> successor = (index==size ? header : entry(index));    
            // 设置“当前要插入节点的前一个节点”    
            Entry<E> predecessor = successor.previous;    
            // 将集合(c)全部插入双向链表中    
            for (int i=0; i<numNew; i++) {    
                Entry<E> e = new Entry<E>((E)a[i], successor, predecessor);    
                predecessor.next = e;    
                predecessor = e;    
            }    
            successor.previous = predecessor;    
       
            // 调整LinkedList的实际大小    
            size += numNew;    
            return true;    
        }    
       
        // 清空双向链表    
        public void clear() {    
            Entry<E> e = header.next;    
            // 从表头开始,逐个向后遍历;对遍历到的节点执行一下操作:    
            // (01) 设置前一个节点为null     
            // (02) 设置当前节点的内容为null     
            // (03) 设置后一个节点为“新的当前节点”    
            while (e != header) {    
                Entry<E> next = e.next;    
                e.next = e.previous = null;    
                e.element = null;    
                e = next;    
            }    
            header.next = header.previous = header;    
            // 设置大小为0    
            size = 0;    
            modCount++;    
        }    
       
        // 返回LinkedList指定位置的元素    
        public E get(int index) {    
            return entry(index).element;    
        }    
       
        // 设置index位置对应的节点的值为element    
        public E set(int index, E element) {    
            Entry<E> e = entry(index);    
            E oldVal = e.element;    
            e.element = element;    
            return oldVal;    
        }    
         
        // 在index前添加节点,且节点的值为element    
        public void add(int index, E element) {    
            addBefore(element, (index==size ? header : entry(index)));    
        }    
       
        // 删除index位置的节点    
        public E remove(int index) {    
            return remove(entry(index));    
        }    
       
        // 获取双向链表中指定位置的节点    
        private Entry<E> entry(int index) {    
            if (index < 0 || index >= size)    
                throw new IndexOutOfBoundsException("Index: "+index+    
                                                    ", Size: "+size);    
            Entry<E> e = header;    
            // 获取index处的节点。    
            // 若index < 双向链表长度的1/2,则从前先后查找;    
            // 否则,从后向前查找。    
            if (index < (size >> 1)) {    
                for (int i = 0; i <= index; i++)    
                    e = e.next;    
            } else {    
                for (int i = size; i > index; i--)    
                    e = e.previous;    
            }    
            return e;    
        }    
       
        // 从前向后查找,返回“值为对象(o)的节点对应的索引”    
        // 不存在就返回-1    
        public int indexOf(Object o) {    
            int index = 0;    
            if (o==null) {    
                for (Entry e = header.next; e != header; e = e.next) {    
                    if (e.element==null)    
                        return index;    
                    index++;    
                }    
            } else {    
                for (Entry e = header.next; e != header; e = e.next) {    
                    if (o.equals(e.element))    
                        return index;    
                    index++;    
                }    
            }    
            return -1;    
        }    
       
        // 从后向前查找,返回“值为对象(o)的节点对应的索引”    
        // 不存在就返回-1    
        public int lastIndexOf(Object o) {    
            int index = size;    
            if (o==null) {    
                for (Entry e = header.previous; e != header; e = e.previous) {    
                    index--;    
                    if (e.element==null)    
                        return index;    
                }    
            } else {    
                for (Entry e = header.previous; e != header; e = e.previous) {    
                    index--;    
                    if (o.equals(e.element))    
                        return index;    
                }    
            }    
            return -1;    
        }    
       
        // 返回第一个节点    
        // 若LinkedList的大小为0,则返回null    
        public E peek() {    
            if (size==0)    
                return null;    
            return getFirst();    
        }    
       
        // 返回第一个节点    
        // 若LinkedList的大小为0,则抛出异常    
        public E element() {    
            return getFirst();    
        }    
       
        // 删除并返回第一个节点    
        // 若LinkedList的大小为0,则返回null    
        public E poll() {    
            if (size==0)    
                return null;    
            return removeFirst();    
        }    
       
        // 将e添加双向链表末尾    
        public boolean offer(E e) {    
            return add(e);    
        }    
       
        // 将e添加双向链表开头    
        public boolean offerFirst(E e) {    
            addFirst(e);    
            return true;    
        }    
       
        // 将e添加双向链表末尾    
        public boolean offerLast(E e) {    
            addLast(e);    
            return true;    
        }    
       
        // 返回第一个节点    
        // 若LinkedList的大小为0,则返回null    
        public E peekFirst() {    
            if (size==0)    
                return null;    
            return getFirst();    
        }    
       
        // 返回最后一个节点    
        // 若LinkedList的大小为0,则返回null    
        public E peekLast() {    
            if (size==0)    
                return null;    
            return getLast();    
        }    
       
        // 删除并返回第一个节点    
        // 若LinkedList的大小为0,则返回null    
        public E pollFirst() {    
            if (size==0)    
                return null;    
            return removeFirst();    
        }    
       
        // 删除并返回最后一个节点    
        // 若LinkedList的大小为0,则返回null    
        public E pollLast() {    
            if (size==0)    
                return null;    
            return removeLast();    
        }    
       
        // 将e插入到双向链表开头    
        public void push(E e) {    
            addFirst(e);    
        }    
       
        // 删除并返回第一个节点    
        public E pop() {    
            return removeFirst();    
        }    
       
        // 从LinkedList开始向后查找,删除第一个值为元素(o)的节点    
        // 从链表开始查找,如存在节点的值为元素(o)的节点,则删除该节点    
        public boolean removeFirstOccurrence(Object o) {    
            return remove(o);    
        }    
       
        // 从LinkedList末尾向前查找,删除第一个值为元素(o)的节点    
        // 从链表开始查找,如存在节点的值为元素(o)的节点,则删除该节点    
        public boolean removeLastOccurrence(Object o) {    
            if (o==null) {    
                for (Entry<E> e = header.previous; e != header; e = e.previous) {    
                    if (e.element==null) {    
                        remove(e);    
                        return true;    
                    }    
                }    
            } else {    
                for (Entry<E> e = header.previous; e != header; e = e.previous) {    
                    if (o.equals(e.element)) {    
                        remove(e);    
                        return true;    
                    }    
                }    
            }    
            return false;    
        }    
       
        // 返回“index到末尾的全部节点”对应的ListIterator对象(List迭代器)    
        public ListIterator<E> listIterator(int index) {    
            return new ListItr(index);    
        }    
       
        // List迭代器    
        private class ListItr implements ListIterator<E> {    
            // 上一次返回的节点    
            private Entry<E> lastReturned = header;    
            // 下一个节点    
            private Entry<E> next;    
            // 下一个节点对应的索引值    
            private int nextIndex;    
            // 期望的改变计数。用来实现fail-fast机制。    
            private int expectedModCount = modCount;    
       
            // 构造函数。    
            // 从index位置开始进行迭代    
            ListItr(int index) {    
                // index的有效性处理    
                if (index < 0 || index > size)    
                    throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size);    
                // 若 “index 小于 ‘双向链表长度的一半’”,则从第一个元素开始往后查找;    
                // 否则,从最后一个元素往前查找。    
                if (index < (size >> 1)) {    
                    next = header.next;    
                    for (nextIndex=0; nextIndex<index; nextIndex++)    
                        next = next.next;    
                } else {    
                    next = header;    
                    for (nextIndex=size; nextIndex>index; nextIndex--)    
                        next = next.previous;    
                }    
            }    
       
            // 是否存在下一个元素    
            public boolean hasNext() {    
                // 通过元素索引是否等于“双向链表大小”来判断是否达到最后。    
                return nextIndex != size;    
            }    
       
            // 获取下一个元素    
            public E next() {    
                checkForComodification();    
                if (nextIndex == size)    
                    throw new NoSuchElementException();    
       
                lastReturned = next;    
                // next指向链表的下一个元素    
                next = next.next;    
                nextIndex++;    
                return lastReturned.element;    
            }    
       
            // 是否存在上一个元素    
            public boolean hasPrevious() {    
                // 通过元素索引是否等于0,来判断是否达到开头。    
                return nextIndex != 0;    
            }    
       
            // 获取上一个元素    
            public E previous() {    
                if (nextIndex == 0)    
                throw new NoSuchElementException();    
       
                // next指向链表的上一个元素    
                lastReturned = next = next.previous;    
                nextIndex--;    
                checkForComodification();    
                return lastReturned.element;    
            }    
       
            // 获取下一个元素的索引    
            public int nextIndex() {    
                return nextIndex;    
            }    
       
            // 获取上一个元素的索引    
            public int previousIndex() {    
                return nextIndex-1;    
            }    
       
            // 删除当前元素。    
            // 删除双向链表中的当前节点    
            public void remove() {    
                checkForComodification();    
                Entry<E> lastNext = lastReturned.next;    
                try {    
                    LinkedList.this.remove(lastReturned);    
                } catch (NoSuchElementException e) {    
                    throw new IllegalStateException();    
                }    
                if (next==lastReturned)    
                    next = lastNext;    
                else   
                    nextIndex--;    
                lastReturned = header;    
                expectedModCount++;    
            }    
       
            // 设置当前节点为e    
            public void set(E e) {    
                if (lastReturned == header)    
                    throw new IllegalStateException();    
                checkForComodification();    
                lastReturned.element = e;    
            }    
       
            // 将e添加到当前节点的前面    
            public void add(E e) {    
                checkForComodification();    
                lastReturned = header;    
                addBefore(e, next);    
                nextIndex++;    
                expectedModCount++;    
            }    
       
            // 判断 “modCount和expectedModCount是否相等”,依次来实现fail-fast机制。    
            final void checkForComodification() {    
                if (modCount != expectedModCount)    
                throw new ConcurrentModificationException();    
            }    
        }    
       
        // 双向链表的节点所对应的数据结构。    
        // 包含3部分:上一节点,下一节点,当前节点值。    
        private static class Entry<E> {    
            // 当前节点所包含的值    
            E element;    
            // 下一个节点    
            Entry<E> next;    
            // 上一个节点    
            Entry<E> previous;    
       
            /**   
             * 链表节点的构造函数。   
             * 参数说明:   
             *   element  —— 节点所包含的数据   
             *   next      —— 下一个节点   
             *   previous —— 上一个节点   
             */   
            Entry(E element, Entry<E> next, Entry<E> previous) {    
                this.element = element;    
                this.next = next;    
                this.previous = previous;    
            }    
        }    
       
        // 将节点(节点数据是e)添加到entry节点之前。    
        private Entry<E> addBefore(E e, Entry<E> entry) {    
            // 新建节点newEntry,将newEntry插入到节点e之前;并且设置newEntry的数据是e    
            Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);    
            newEntry.previous.next = newEntry;    
            newEntry.next.previous = newEntry;    
            // 修改LinkedList大小    
            size++;    
            // 修改LinkedList的修改统计数:用来实现fail-fast机制。    
            modCount++;    
            return newEntry;    
        }    
       
        // 将节点从链表中删除    
        private E remove(Entry<E> e) {    
            if (e == header)    
                throw new NoSuchElementException();    
       
            E result = e.element;    
            e.previous.next = e.next;    
            e.next.previous = e.previous;    
            e.next = e.previous = null;    
            e.element = null;    
            size--;    
            modCount++;    
            return result;    
        }    
       
        // 反向迭代器    
        public Iterator<E> descendingIterator() {    
            return new DescendingIterator();    
        }    
       
        // 反向迭代器实现类。    
        private class DescendingIterator implements Iterator {    
            final ListItr itr = new ListItr(size());    
            // 反向迭代器是否下一个元素。    
            // 实际上是判断双向链表的当前节点是否达到开头    
            public boolean hasNext() {    
                return itr.hasPrevious();    
            }    
            // 反向迭代器获取下一个元素。    
            // 实际上是获取双向链表的前一个节点    
            public E next() {    
                return itr.previous();    
            }    
            // 删除当前节点    
            public void remove() {    
                itr.remove();    
            }    
        }    
       
       
        // 返回LinkedList的Object[]数组    
        public Object[] toArray() {    
        // 新建Object[]数组    
        Object[] result = new Object[size];    
            int i = 0;    
            // 将链表中所有节点的数据都添加到Object[]数组中    
            for (Entry<E> e = header.next; e != header; e = e.next)    
                result[i++] = e.element;    
        return result;    
        }    
       
        // 返回LinkedList的模板数组。所谓模板数组,即可以将T设为任意的数据类型    
        public <T> T[] toArray(T[] a) {    
            // 若数组a的大小 < LinkedList的元素个数(意味着数组a不能容纳LinkedList中全部元素)    
            // 则新建一个T[]数组,T[]的大小为LinkedList大小,并将该T[]赋值给a。    
            if (a.length < size)    
                a = (T[])java.lang.reflect.Array.newInstance(    
                                    a.getClass().getComponentType(), size);    
            // 将链表中所有节点的数据都添加到数组a中    
            int i = 0;    
            Object[] result = a;    
            for (Entry<E> e = header.next; e != header; e = e.next)    
                result[i++] = e.element;    
       
            if (a.length > size)    
                a[size] = null;    
       
            return a;    
        }    
       
       
        // 克隆函数。返回LinkedList的克隆对象。    
        public Object clone() {    
            LinkedList<E> clone = null;    
            // 克隆一个LinkedList克隆对象    
            try {    
                clone = (LinkedList<E>) super.clone();    
            } catch (CloneNotSupportedException e) {    
                throw new InternalError();    
            }    
       
            // 新建LinkedList表头节点    
            clone.header = new Entry<E>(null, null, null);    
            clone.header.next = clone.header.previous = clone.header;    
            clone.size = 0;    
            clone.modCount = 0;    
       
            // 将链表中所有节点的数据都添加到克隆对象中    
            for (Entry<E> e = header.next; e != header; e = e.next)    
                clone.add(e.element);    
       
            return clone;    
        }    
       
        // java.io.Serializable的写入函数    
        // 将LinkedList的“容量,所有的元素值”都写入到输出流中    
        private void writeObject(java.io.ObjectOutputStream s)    
            throws java.io.IOException {    
            // Write out any hidden serialization magic    
            s.defaultWriteObject();    
       
            // 写入“容量”    
            s.writeInt(size);    
       
            // 将链表中所有节点的数据都写入到输出流中    
            for (Entry e = header.next; e != header; e = e.next)    
                s.writeObject(e.element);    
        }    
       
        // java.io.Serializable的读取函数:根据写入方式反向读出    
        // 先将LinkedList的“容量”读出,然后将“所有的元素值”读出    
        private void readObject(java.io.ObjectInputStream s)    
            throws java.io.IOException, ClassNotFoundException {    
            // Read in any hidden serialization magic    
            s.defaultReadObject();    
       
            // 从输入流中读取“容量”    
            int size = s.readInt();    
       
            // 新建链表表头节点    
            header = new Entry<E>(null, null, null);    
            header.next = header.previous = header;    
       
            // 从输入流中将“所有的元素值”并逐个添加到链表中    
            for (int i=0; i<size; i++)    
                addBefore((E)s.readObject(), header);    
        }    
    }   
    
    Learn ,Practice ,Summary !
  • 相关阅读:
    PHP 上传文件限制
    vim设置golang语法高亮 (Centos)
    linux下安装配置go语言环境
    Vim升华之树形目录插件NERDTree安装图解(ubuntu)
    linux下配置Node.js环境
    RabbitMQ的使用(二)- RabbitMQ服务在单机中做集群
    RabbitMQ的使用(一)- RabbitMQ服务安装
    Exceptionless(二)
    Exceptionless
    SQL Server2012如何打开2016的profiler文件
  • 原文地址:https://www.cnblogs.com/daminzhou/p/8406460.html
Copyright © 2011-2022 走看看