常用集合ArrayList,LinkedList,HashMap,HashSet源码分析

(一)ArrayList,可自动扩充容量的动态数组

public class ArrayList<E> extends AbstractList<E> implements List<E>,
        RandomAccess, Cloneable, java.io.Serializable {
    private static final long serialVersionUID = 8683452581122892189L;

    /**
     * 
     * 所有ArrayList的元素都存储在此对象数组当中
     * ArrayList的容量就是此数组的长度
     */
    private transient Object[] elementData;

    /**
     * 实际拥有的元素的数量
     * 
     * @serial
     */
    private int size;

    /**
     * 构造方法一,指定elementData数组初始长度
     */
    public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)    //小于0则抛出IllegalArgumentException
            throw new IllegalArgumentException("Illegal Capacity: "
                    + initialCapacity);
        this.elementData = new Object[initialCapacity];
    }

    /**
     * 构造方法二,默认elementData数组初始长度为10
     */
    public ArrayList() {
        this(10);
    }

    /**
     * 构造方法三,构造一个包含指定 collection 的元素的List
     */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();      //toArray方法由AbstractCollection实现,返回一个对象数组
        size = elementData.length;      //元素的顺序是由迭代器迭代顺序决定的,详情见toArray方法实现
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)   //如果返回的不是一个数组对象
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    }

    /**
     * 修剪ArrayList的容量为实际size长度
     */
    public void trimToSize() {
        modCount++;         //此方法改变了数组结构,需要检测是否同步
        int oldCapacity = elementData.length;
        if (size < oldCapacity) {
            elementData = Arrays.copyOf(elementData, size);
        }
    }

    /**
     * 
     * 扩充数组容量,并指定其最小的容量,即至少容量大小为minCapacity
     */
    public void ensureCapacity(int minCapacity) {
        modCount++;
        int oldCapacity = elementData.length;
        if (minCapacity > oldCapacity) {    //指定最小容量比原来容量大才扩充
            Object oldData[] = elementData;
            int newCapacity = (oldCapacity * 3) / 2 + 1;    //扩充原容量的1.5倍加1
            if (newCapacity < minCapacity)  //扩充后还是小于要求的最小容量,则扩充容量为最小容量
                newCapacity = minCapacity;
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    }

    /**
     * 返回List中的元素个数
     */
    public int size() {
        return size;
    }

    /**
     * List是否不含元素
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 查看o是否包含在ArrayList中,内部调用了indexOf方法实现
     */
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

    /**
     * 父类AbstractList的indexOf方法使用的是list迭代器遍历元素
     * 这里重写了indexOf方法直接遍历数组即可
     * 返回指定元素第一次在数组中出现的索引
     * 如果找不到此元素则返回-1
     */
    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;
    }

    /**
     * 基本同上
     */
    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的浅拷贝实例对象,包含所有元素
     */
    public Object clone() {
        try {
            ArrayList<E> v = (ArrayList<E>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {    //如果未实现Cloneable则会抛出CloneNotSupportedException
            throw new InternalError();
        }
    }

    /**
     * 
     * 返回的对象数组是安全的,因为它是一个全新的对象
     * 操作返回的数组并不会影响到ArrayList对象
     *
     */
    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }

    /**
     * 返回一个指定类型的包含List所有元素的数组
     */
    public <T> T[] toArray(T[] a) {
        if (a.length < size)    //如果a的长度小于List元素个数
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());    //以指定类型返回一个新数组,长度为size
        System.arraycopy(elementData, 0, a, 0, size);   //否则把elementData中元素复制到a
        if (a.length > size)    //如果a的长度大于size则在最后位置加一个null元素,等于的话就不用加了
            a[size] = null;     //这对了解它的实际长度很有效
        return a;
    }

    // Positional Access Operations

    public E get(int index) {
        RangeCheck(index);  //检查是否越界

        return (E) elementData[index];  //直接返回数组某位置的元素即可
    }

    /**
     * 对数组指定所有的值进行替换,并返回上一个值
     */
    public E set(int index, E element) {
        RangeCheck(index);  //检查是否越界

        E oldValue = (E) elementData[index];    //so easy
        elementData[index] = element;
        return oldValue;
    }

    /**
     * 在数组size位置添加一个元素
     * 
     */
    public boolean add(E e) {
        ensureCapacity(size + 1); // modCount++,并检查是否需要扩充容量
        elementData[size++] = e;    //size++
        return true;
    }

    /**
     * 
     * 在指定位置添加一个元素,当前在此位置的元素以及其后面的元素都要向后移动一个位置
     * 此方法的效率较低
     *
     */
    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);   //把原来index位置的元素,复制到index+1的位置,后面的size-index-1长度的元素依次复制
        elementData[index] = element;   //空出的index位置的元素设为element
        size++;
    }

    /**
     * 
     * 移除指定位置的元素,其后面的元素都要向左移动一个位置
     * 此方法的效率较低
     */
    public E remove(int index) {
        RangeCheck(index);

        modCount++;     //modCount是为了检测是否发生了并发操作,详细见AbstractList类
        E oldValue = (E) elementData[index];

        int numMoved = size - index - 1;    //与add相比少移一个元素
        if (numMoved > 0)   //是否移除的是最后一个元素
            System.arraycopy(elementData, index + 1, elementData, index,
                    numMoved);  //index位置的元素被移除了,原来index+1位置的元素复制到index位置,随后的元素依次复制
        elementData[--size] = null; // Let gc do its work,size位置的元素空出来了

        return oldValue;
    }

    /**
     * 
     * 如果o在List中存在,移除第一次出现在List中的o元素
     * 如果o在List中不存在,不做任何操作
     *
     */
    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;
    }

    /*
     * 
     * 与remove(int index)方法差不多,
     * 不过不用检测是否越界与返回原来的index位置的值
     */
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index + 1, elementData, index,
                    numMoved); 
        elementData[--size] = null; // Let gc do its work
    }

    /**
     * 移除所有元素,即把所有元素设为null,size=0
     */
    public void clear() {
        modCount++;

        // Let gc do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;

        size = 0;
    }

    /**
     * 把a中所有元素添加到数组尾部
     */
    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位置开始复制a
        size += numNew;     //size增加
        return numNew != 0;
    }

    /**
     * 
     * 在指定位置开始添加指定集合c中的所有元素
     * 当前位置及其随后位置的元素后移
     */
    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);  //把原来index位置的元素,复制到index+numNew的位置,后面的size-index-1长度的元素依次复制

        System.arraycopy(a, 0, elementData, index, numNew); //空出来的位置填充c
        size += numNew;
        return numNew != 0;
    }

    /**
     * 
     * 移除所有从fromIndex(包含)到toIndex(不包含)范围内的元素,
     * 左移随后的元素.如果toIndex=fromIndex,此操作无影响
     *
     */
    protected void removeRange(int fromIndex, int toIndex) {
        modCount++;
        int numMoved = size - toIndex;
        System.arraycopy(elementData, toIndex, elementData, fromIndex,
                        numMoved);  //把toIndex位置的元素复制到fromIndex,随后的元素依次复制,总共复制numMoved个元素

        // Let gc do its work
        int newSize = size - (toIndex - fromIndex); 
        while (size != newSize) //这里是为了让gc工作,不直接把size设为newSize
            elementData[--size] = null;
    }

    /**
     * 
     * 这里并没有检测index小于0的情况
     * 它总是由数组自己检测,抛出的异常也不同,为ArrayIndexOutOfBoundsException
     */
    private void RangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
                    + size);
    }

    /**
     * 序列化ArrayList,保存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();
        }

    }

    /**
     * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
     * deserialize it).
     */
    private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // 读出数组长度
        int arrayLength = s.readInt();
        Object[] a = elementData = new Object[arrayLength]; //保存

        // 依次读出所有元素
        for (int i = 0; i < size; i++)
            a[i] = s.readObject();
    }
}

(二)LikedList(双向循环链表)

public class LinkedList<E> extends AbstractSequentialList<E> implements
        List<E>, Deque<E>, Cloneable, java.io.Serializable {
    //在第一个节点之前附设的一个节点称为头结点,有元素添加会重设值
    //此变量在序列化时不保存
    private transient Entry<E> header = new Entry<E>(null, null, null); 
    private transient int size = 0;     //List存储的Entry对象个数

    /**
     * 构造方法一,空链表
     */
    public LinkedList() {
        header.next = header.previous = header;  //只有一个头结点的链表
    }

    /**
     * 构造方法二,构造含有指定集合c中所有元素的链表
     * 具体见addAll方法
     */
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

    /**
     * 获取第一个元素的值,即头结点的下一个元素的数据部分
     */
    public E getFirst() {
        if (size == 0)
            throw new NoSuchElementException();

        return header.next.element;
    }

    /**
     * 双向循环链表,你懂得
     */
    public E getLast() {
        if (size == 0)
            throw new NoSuchElementException();

        return header.previous.element;
    }

    /**
     * 移除第一个元素,具体见remove()方法
     */
    public E removeFirst() {
        return remove(header.next);
    }

    /**
     * 移除最后一个元素
     */
    public E removeLast() {
        return remove(header.previous);
    }

    /**
     * 
     * 在链表开始位置添加一个元素
     * 详情见addBefore()
     */
    public void addFirst(E e) {
        addBefore(e, header.next);
    }

    /**
     * 在链表最后位置添加一个元素
     * 详情见addBefore()
     */
    public void addLast(E e) {
        addBefore(e, header);
    }

    /**
     * 查看链表是否包含元素o
     * 详细见indexOf()方法
     */
    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }

    /**
     * 链表所含元素的数量
     */
    public int size() {
        return size;
    }

    /**
     * 跟addLast()方法类似,添加成功返回true
     */
    public boolean add(E e) {
        addBefore(e, header);
        return true;
    }

    /**
     * 假如链表中含有一个或多个o对象,移除第一次出现的o
     * 如果找不到o返回false
     */
    public boolean remove(Object o) {
        if (o == null) {
            for (Entry<E> e = header.next; e != header; e = e.next) {   //从第一个元素开始遍历,每一个Entry对象都包含它下一个元素的信息
                if (e.element == null) {
                    remove(e);
                    return true;
                }
            }
        } else {
            for (Entry<E> e = header.next; e != header; e = e.next) {
                if (o.equals(e.element)) {
                    remove(e);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 
     * 把c中所有元素按顺序添加到链表尾部
     */
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }

    /**
     * 
     * 在指定位置按顺序添加c中所有元素带List中
     * 
     */
    public boolean addAll(int index, Collection<? extends E> c) {
        if (index < 0 || index > size)  //检查是否越界,=size表示添加到最后
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
                    + size);
        Object[] a = c.toArray();
        int numNew = a.length;
        if (numNew == 0)
            return false;
        modCount++;     //对链表结构产生 影响的操作modCount都要加1,通过modCount可以检查是否对链表进行了并发操作

        Entry<E> successor = (index == size ? header : entry(index));
        Entry<E> predecessor = successor.previous;
        for (int i = 0; i < numNew; i++) {  //这里不难,画一个图就出来了,主要是初始化c和修改指针
            //暂时使其next为successor,因为e会赋给前驱,而每次遍历都要修改其前驱的next
            Entry<E> e = new Entry<E>((E) a[i], successor, predecessor);    //把c中元素依次存入Entry,设置其前驱和后继。
            predecessor.next = e;   //重新设置前驱的next指针
            predecessor = e;    //让e变为前驱
        }
        successor.previous = predecessor;   //successor的前驱为c中最后一个元素的引用

        size += numNew;     //长度加
        return true;
    }

    /**
     * 移除链表中所有元素
     */
    public void clear() {
        Entry<E> e = header.next;
        while (e != header) {   //表示不是只有一个头结点的空链表
            Entry<E> next = e.next;
            e.next = e.previous = null; //let gc work
            e.element = null;
            e = next;
        }
        header.next = header.previous = header; //初始头结点
        size = 0;
        modCount++;
    }

    // Positional Access Operations

    /**
     * 返回指定位置的元素时
     */
    public E get(int index) {
        return entry(index).element;
    }

    /**
     * 设置指定位置的元素
     */
    public E set(int index, E element) {
        Entry<E> e = entry(index);
        E oldVal = e.element;
        e.element = element;
        return oldVal;
    }

    /**
     * 
     * 把指定元素添加到指定位置,需先定位到此位置的节点
     * 详情见addBefore()
     */
    public void add(int index, E element) {
        addBefore(element, (index == size ? header : entry(index)));
    }

    /**
     * 移除指定位置的元素
     */
    public E remove(int index) {
        return remove(entry(index));
    }

    /**
     * 
     * 返回指定索引位置的Entry对象,需要依次遍历得到。
     * 这里稍做了一下优化,如果index < size/2 从前面开始遍历
     * 如果index >= size/2 从后面开始遍历
     */
    private Entry<E> entry(int index) {
        if (index < 0 || index >= size) //index在0(包含)到size(不包含)之间,索引从0开始
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
                    + size);
        Entry<E> e = header;
        if (index < (size >> 1)) {
            for (int i = 0; i <= index; i++)
                e = e.next; //依次调用e.next才能得到,需调用index+1次,因为它是从头结点开始的
        } else {
            for (int i = size; i > index; i--)
                e = e.previous; //依次调用e.previous才能得到
        }
        return e;
    }

    // Search Operations

    /**
     * 
     * 返回o第一次出现的位置,如果在List中找不到o返回-1
     */
    public int indexOf(Object o) {
        int index = 0;  //链表的索引也是从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;
    }

    /**
     * 双向循环链表,从后面开始遍历即可
     */
    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;
    }

    // Queue operations.有关队列的基本操作

    /**
     * 如果链表长度不为空,获取第一个元素
     * 否则返回null
     */
    public E peek() {
        if (size == 0)
            return null;
        return getFirst();
    }

    /**
     * 跟peek方法相似,不过这里size为0的话直接抛出异常
     */
    public E element() {
        return getFirst();
    }

    /**
     * 如果链表长度不为空,移除第一个元素,并返回它
     * 否则返回null
     */
    public E poll() {
        if (size == 0)
            return null;
        return removeFirst();
    }

    /**
     * 与poll方法类似,不过长度为空,即header.next = header
     * 抛出NoSuchElementException
     */
    public E remove() {
        return removeFirst();
    }

    /**
     * 添加一个元素到链表尾部
     */
    public boolean offer(E e) {
        return add(e);
    }

    // Deque operations
    /**
     * 添加一个元素到头结点之后,原来的第一个节点之前
     */
    public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }

    /**
     * 在尾部添加一个元素
     */
    public boolean offerLast(E e) {
        addLast(e);
        return true;
    }

    /**
     * 获取第一个元素,如果size为0,返回空
     * 否则返回第一个元素
     */
    public E peekFirst() {
        if (size == 0)
            return null;
        return getFirst();
    }

    /**
     * 获取最后一个元素,如果size为0,返回空
     * 否则返回最后一个元素
     */
    public E peekLast() {
        if (size == 0)
            return null;
        return getLast();
    }

    /**
     * 
     * 移除第一个元素并返回它
     * 如果size为0则直接返回null
     */
    public E pollFirst() {
        if (size == 0)
            return null;
        return removeFirst();
    }

    /**
     * 移除最后一个元素并返回它
     * 如果size为0则直接返回null
     */
    public E pollLast() {
        if (size == 0)
            return null;
        return removeLast();
    }

    /**
     * 在开始位置添加一个元素
     */
    public void push(E e) {
        addFirst(e);
    }

    /**
     * 移除第一个元素
     */
    public E pop() {
        return removeFirst();
    }

    /**
     * 
     * 移除第一次出现的指定的元素
     * 如果遍历整个List后没有找到o,则不做任何改变
     * 
     */
    public boolean removeFirstOccurrence(Object o) {
        return remove(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;
    }

    /**
     * 
     * 返回一个list-iterator.
     */
    public ListIterator<E> listIterator(int index) {
        return new ListItr(index);
    }

    /**
     * 重新 实现ListIterator,使其跟符合链表的特性
     * iterator方法由AbstractSequentialList实现了,
     * 但是调用的还是本ListIterator。只不过只能使用iterator接口的方法
     * */
    private class ListItr implements ListIterator<E> {
        private Entry<E> lastReturned = header;     //上一次调用next或previous返回的元素,没有调用next则为头结点
        private Entry<E> next;  //下一次调用next方法返回的元素
        private int nextIndex;  //下一次调用next返回的元素的索引
        private int expectedModCount = modCount;    //用来检测遍历过程中是否产生了并发操作

        ListItr(int index) {    //构造器,是迭代器定位到index位置,要返回index位置的元素需调用一次next()方法时
            if (index < 0 || index > size)  
                throw new IndexOutOfBoundsException("Index: " + index
                        + ", Size: " + size);
            if (index < (size >> 1)) {  //从前面开始遍历
                next = header.next;  //这是index为0的元素
                for (nextIndex = 0; nextIndex < index; nextIndex++)
                    next = next.next;   //最终next为第index个元素,index从0开始
            } else {        //从后面开始遍历
                next = header;
                for (nextIndex = size; nextIndex > index; nextIndex--)
                    next = next.previous;   //最终next为第index个元素,index从0开始
            }
        }

        public boolean hasNext() {  //size位置可没有元素
            return nextIndex != size;
        }

        public E next() {
            checkForComodification();
            if (nextIndex == size)
                throw new NoSuchElementException();

            lastReturned = next;
            next = next.next;   //这里与ArrayList中的cursor何其相似
            nextIndex++;
            return lastReturned.element;
        }

        public boolean hasPrevious() {
            return nextIndex != 0;
        }

        public E previous() {
            if (nextIndex == 0)
                throw new NoSuchElementException();

            lastReturned = next = next.previous;
            nextIndex--;
            checkForComodification();
            return lastReturned.element;
        }

        public int nextIndex() {    //返回下一次调用next返回的元素的索引
            return nextIndex;
        }

        public int previousIndex() {    //返回下一次调用previous返回的元素的索引
            return nextIndex - 1;
        }

        public void remove() {
            checkForComodification();
            Entry<E> lastNext = lastReturned.next;
            try {
                LinkedList.this.remove(lastReturned);   //移除上一层调用next()或previous返回的元素
            } catch (NoSuchElementException e) {
                throw new IllegalStateException();
            }
            if (next == lastReturned)   //表明是调用previous后才调用remove方法
                next = lastNext;
            else
                nextIndex--;        //元素减少。nextIndex--
            lastReturned = header;  //重置lastReturned
            expectedModCount++;
        }

        public void set(E e) {
            if (lastReturned == header)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.element = e;
        }

        public void add(E e) {
            checkForComodification();
            lastReturned = header;
            addBefore(e, next); //在上一次调用next返回的元素之后,在上次调用previous返回的元素之前添加e
            nextIndex++;    //元素增加,索引增加,保证下次调用next()不是返回添加的元素
            expectedModCount++;
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

    /**
     * LinkedList的元素节点,保存当前节点的元素
     * 以及下一个节点,和上一个节点的引用
     * 由此看出LinkedList是一个双向链表
     */
    private static class Entry<E> {
        E element;          //当前节点元素
        Entry<E> next;      //下一个节点引用
        Entry<E> previous;  //上一个节点引用

        Entry(E element, Entry<E> next, Entry<E> previous) {
            this.element = element;
            this.next = next;
            this.previous = previous;
        }
    }

    /**
     *  在entry之前添加一个节点e
     * 
     */
    private Entry<E> addBefore(E e, Entry<E> entry) {
        Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); //新节点的前驱和后继,只有一个元素的话前驱和后继都为header
        newEntry.previous.next = newEntry;  //新节点的前驱的后继为新节点,只包含newEntry一个元素的话修改的是头结点的next
        newEntry.next.previous = newEntry;  //新节点的后继的前驱为新节点,只包含newEntry一个元素的话修改的是头结点的previous
        size++;
        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的前驱的后继等于e的后继
        e.next.previous = e.previous;   //e的后继的前驱等于e的前驱
        e.next = e.previous = null; //let gc work
        e.element = null;
        size--;     //size--
        modCount++;
        return result;
    }

    /**
     * 逆序返回所有元素的迭代器
     */
    public Iterator<E> descendingIterator() {
        return new DescendingIterator();
    }

    /** Adapter to provide descending iterators via ListItr.previous */
    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();
        }
    }

    /**
     * 返回一个LikedList的浅拷贝对象
     */
    public Object clone() {
        LinkedList<E> clone = null;
        try {
            clone = (LinkedList<E>) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }

        // Put clone into "virgin" state,即重置其为初始状态
        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;
    }

    /**
     * 返回一个新建对象数组,包含链表中所有元素
     */
    public Object[] toArray() {
        Object[] result = new Object[size]; //新建一size长度对象数组
        int i = 0;
        for (Entry<E> e = header.next; e != header; e = e.next) //遍历赋值
            result[i++] = e.element;
        return result;
    }

    /**
     * 所有toArray方法都是一个思想...
     * 只是遍历方式不同
     * */
    public <T> T[] toArray(T[] a) {
        if (a.length < size)    //如果指定数组长度小于size,新建一数组
            a = (T[]) java.lang.reflect.Array.newInstance(a.getClass()
                    .getComponentType(), size);
        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) //同ArrayList
            a[size] = null;

        return a;
    }

    private static final long serialVersionUID = 876323262645176354L;

    /**
     * 序列化LikedList,保存其状态
     */
    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);
    }

    /**
     * 从流中读取
     */
    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
        header = new Entry<E>(null, null, null);
        header.next = header.previous = header;

        // 按顺序写入所有元素
        for (int i = 0; i < size; i++)
            addBefore((E) s.readObject(), header);
    }
}

(三)HashMap(数组加链表的结合体)

/**
 * 作用:用于实现快速查找
 * HashMap实现的数据结构:动态数组和链表的结合体
 * */
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>,
        Cloneable, Serializable {

    /**
     * 默认初始数组容量,必须为2的幂
     */
    static final int DEFAULT_INITIAL_CAPACITY = 16;

    /**
     *
     * 最大容量为1 * 2^30 即2的30次方
     */
    static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * 
     * hashMap的加载系数,当数组中的元素增多时,通过hash函数算出的数组下标
     * 相同几率增加。为保证查找的效率,当数组中的元素超过
     * load_factor * table.length 时就要扩充容量
     * 默认加载系数为0.75
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * 
     * 数组存放Entry对象,单向链表的第一个元素,
     * 通过它可以遍历整个链表。
     * table长度会在需要时进行扩充,table长度始终为2的幂
     */
    transient Entry[] table;

    /**
     * key-value键值对个数
     */
    transient int size;

    /**
     * HashMap size >= threshlod时就扩充数组容量
     */
    int threshold;

    /**
     * hash表加载因子
     */
    final float loadFactor;

    /**
     * 
     * hash表发生结构性改变的次数,这些方法包括,put,remove等对size进行改变的操作
     * 用iterator遍历时可以用来检测是否对HashMap进行了并发操作
     */
    transient volatile int modCount;

    /**
     * 根据指定的初始容量和加载系数构建hashMap
     * 初始容量如果不是2的幂,会被构造成2的幂
     */
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)    
            throw new IllegalArgumentException("Illegal initial capacity: "
                    + initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: "
                    + loadFactor);

        //找到一个2的幂的数,使其大于等于初始容量
        int capacity = 1;
        while (capacity < initialCapacity)  
            capacity <<= 1;         // capacity = capacity << 1,左移一位 

        this.loadFactor = loadFactor;
        threshold = (int) (capacity * loadFactor);
        table = new Entry[capacity];
        init(); //所有构造方法都含有此空方法,做一些其他初始化操作。根据业务要求,可由其子类实现
    }

    /**
     * 根据指定容量与默认加载系数构建HashMap
     */
    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    /**
     * 采用默认容量16与默认加载系数0.75构建HashMap
     */
    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        threshold = (int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
        init();
    }

    /**
     * 
     * 根据指定Map中的键值对,默认加载因子构建HashMap
     */
    public HashMap(Map<? extends K, ? extends V> m) {
        this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, //size要小于容量*0.75
                DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
        putAllForCreate(m); 
    }

    // internal utilities

    /**
     *
     * 在new table之后,在添加元素之前被调用
     */
    void init() {
    }

    /**
     * 
     * hash算法,根据key的hashCode计算其hash值
     * 此算法看的一知半解,大家有兴趣可以查看其它资料
     * >>>无符号右移     ^按位异或
     */
    static int hash(int h) {
        // 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);
    }

    /**
     * 根据hash值与数组长度计算其数组索引。
     * length为2的幂,使不同hash通过h&(length-1)产生的索引尽量不同,即减少碰撞。
     * 如果产生的索引都不同,通过找到索引就可以直接找到value,而不需要遍历链表。
     * 可以使产生的索引始终在table索引范围之内
     * 此方法详细解析可见:http://www.iteye.com/topic/539465
     */
    static int indexFor(int h, int length) {
        return h & (length - 1);
    }

    /**
     * 键值对数目
     */
    public int size() {
        return size;
    }

    /**
     * 判断hashMap是否为空
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 
     * 通过key值获得value,如果没有找到此key则返回null。
     * 不过返回null也可能是其value为null
     * 通过contain方法可判断Map中是否含有此键
     * 
     */
    public V get(Object key) {
        if (key == null)    //空键另外处理
            return getForNullKey();
        int hash = hash(key.hashCode());
        //定位到index,并查看e的下一个节点是否为null,否则继续遍历
        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.equals(k)))
                return e.value;
        }
        return null;
    }

    /**
     * 
     * 空键的hash值为0,所以其数组中的索引为0.
     * 独立把此方法分离出来是为了提高两个最常用的方法get和put的性能,
     * 但在其它情况下此方法被合并了.
     */
    private V getForNullKey() {
        for (Entry<K, V> e = table[0]; e != null; e = e.next) {
            if (e.key == null)
                return e.value;
        }
        return null;
    }

    /**
     * 如果Map中含有此key返回true.
     * 具体见getEntry.
     */
    public boolean containsKey(Object key) {
        return getEntry(key) != null;
    }

    /**
     * 
     * 通过返回Entry而不是value可确保Map中是否含有此key
     */
    final Entry<K, V> getEntry(Object key) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash
                    && ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }

    /**
     * 
     * replaced.
     * 通过指定的key值存储指定value,如果Map中含有此key则用指定value替换old value
     */
    public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        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;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);   //当你调用put并在替换老值时会调用此方法,假如你在这个时候想做一些额外操作可继承Entry重写此方法
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }


    private V putForNullKey(V value) {
        for (Entry<K, V> e = table[0]; e != null; e = e.next) {
            if (e.key == null) {    //如果含有此null key替换老值
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        modCount++;
        addEntry(0, null, value, 0);    //否则添加此Entry到数组
        return null;
    }

    /**
     * 
     * 此方法用来替代put方法,不会调整table大小。
     * 此方法在确认map键值对个数始终小于table.length * load_factor,
     * 添加元素时调用。主要是为了提高性能
     */
    private void putForCreate(K key, V value) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        int i = indexFor(hash, table.length);

        /**
         * 
         * 查看是否存在同样的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;
            }
        }
        //否则添加一个Entry对象
        createEntry(hash, key, value, i);
    }

    /**
     * 依次遍历添加
     * */
    private void putAllForCreate(Map<? extends K, ? extends V> m) {
        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中元素越来越多时,发生碰撞的几率增大,为提高效率,当元素超过
     * threshold时就要对数组进行扩充,扩充后,原数组中所有数据都要重新计算
     * 其在新数组中的位置,所以每扩充一次对性能影响是非常大的。
     */
    void resize(int newCapacity) {
        Entry[] oldTable = table;
        int oldCapacity = oldTable.length;
        if (oldCapacity == MAXIMUM_CAPACITY) {  //如果数组容量已经最大,不再扩充。
            threshold = Integer.MAX_VALUE;      //使threshold = Integer.MAX_VALUE,使resize方法不再被调用
            return;
        }

        Entry[] newTable = new Entry[newCapacity];
        transfer(newTable);
        table = newTable;
        threshold = (int) (newCapacity * loadFactor);
    }

    /**
     * 
     * 把table中所有的Entry对象转移到newTabel
     */
    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);  //根据新容量重新计算index
                    e.next = newTable[i];   //最后添加的节点放最前面
                    newTable[i] = e;
                    e = next;
                } while (e != null);
            }
        }
    }

    /**
     *
     * 把所有元素从知道map中复制到本map
     */
    public void putAll(Map<? extends K, ? extends V> m) {
        int numKeysToBeAdded = m.size();
        if (numKeysToBeAdded == 0)
            return;

        /*
         * 
         * 如果numKeysToBeAdded大于或等于threshold就扩展map
         * 这是一个保守的方法。本来的条件应该是(m.size() + size) >= threshold,
         * 但是如果所有被添加的元素的key值在本map中都存在,map扩充的容量将是
         * 最佳容量的两倍。这极大的浪费了空间,所以采用此保守的方法计算newCapacity。
         * 否则不再此处扩充就在put方法中进行扩充
         */
        if (numKeysToBeAdded > threshold) {
            int targetCapacity = (int) (numKeysToBeAdded / loadFactor + 1);
            if (targetCapacity > MAXIMUM_CAPACITY)
                targetCapacity = MAXIMUM_CAPACITY;
            int newCapacity = table.length;
            while (newCapacity < targetCapacity)
                newCapacity <<= 1;  
            if (newCapacity > table.length)
                resize(newCapacity);
        }

        //依次遍历添加
        for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = 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移除Entry对象
     */
    final Entry<K, V> removeEntryForKey(Object key) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        int i = indexFor(hash, table.length);
        Entry<K, V> prev = table[i];
        Entry<K, V> e = prev;

        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)  //表明链表只有一个Entry对象
                    table[i] = next;
                else
                    prev.next = next;   //修改指针
                e.recordRemoval(this);  //在移除元素时调用
                return e;
            }
            prev = e;
            e = next;
        }

        return e;
    }

    /**
     * 同remove方法基本相似
     */
    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;

        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;
    }

    /**
     * 移除所有元素
     */
    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) {
        if (value == null)
            return containsNullValue();

        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;
    }

    /**
     * 是否包含空值
     */
    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的浅拷贝实例
     */
    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();
        result.putAllForCreate(this);   //依次添加本map所有元素到浅拷贝的map实例中

        return result;
    }

    static class Entry<K, V> implements Map.Entry<K, V> {
        final K key;
        V value;
        Entry<K, V> next;
        final int hash;

        /**
         * Creates new entry.
         */
        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的equals方法,键值相等即Entry对象相等
        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方法,异或key与value的hashCode值
         */
        public final int hashCode() {
            return (key == null ? 0 : key.hashCode())
                    ^ (value == null ? 0 : value.hashCode());
        }

        public final String toString() {
            return getKey() + "=" + getValue();
        }

        /**
         *
         * 当添加一键值对,发现键已存在时调用此方法
         *  可以继承Entry对象重写此方法
         */
        void recordAccess(HashMap<K, V> m) {
        }

        /**
         * 当有Entry对象被移除时,此方法被调用。
         * 可以继承Entry对象重写此方法
         */
        void recordRemoval(HashMap<K, V> m) {
        }
    }

    /**
     * 
     * 如果适当此方法会resize table
     */
    void addEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K, V> e = table[bucketIndex];  
        table[bucketIndex] = new Entry<K, V>(hash, key, value, e);
        if (size++ >= threshold)    //如果size超过threshold就调整数组容量大小为原来的两倍
            resize(2 * table.length);
    }

    /**
     *
     * 与addEntry方法类似。但是方法不需要担心容量的扩充
     */
    void createEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K, V> e = table[bucketIndex]; //如果此节点已经有一个Entry对象,返回e,否则返回null
        table[bucketIndex] = new Entry<K, V>(hash, key, value, e);  //以新加入的节点作为第一个节点
        size++;
    }

    /**
     * 抽象类,next方法由其子类实现,
     * 不同的next方法返回不同的迭代器
     * 包括key,value,keySet迭代器
     * */
    private abstract class HashIterator<E> implements Iterator<E> {
        Entry<K, V> next; // next entry to return
        int expectedModCount; // For fast-fail
        int index; // current slot
        Entry<K, V> current; // current entry

        HashIterator() {
            expectedModCount = modCount;
            if (size > 0) { // advance to first entry
                Entry[] t = table;
                //遍历直到获取第一个Entry对象,因为有的索引可能为空
                while (index < t.length && (next = t[index++]) == null) 
                    ;
            }
        }

        public final boolean hasNext() {
            return next != null;
        }

        /**
         * 返回下一个Entry对象
         * */
        final Entry<K, V> nextEntry() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            Entry<K, V> e = next;
            if (e == null)
                throw new NoSuchElementException();

            if ((next = e.next) == null) {
                Entry[] t = table;
                //继续找不为空的索引中的Entry对象
                while (index < t.length && (next = t[index++]) == null)
                    ;
            }
            current = e;
            return e;
        }

        /**
         * 移除当前Entry对象,即调用nextEntry返回的Entry对象
         */
        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);  //此方法会改变modCount
            expectedModCount = modCount;    //所以可以用此语句检测是否产生了并发操作
        }

    }

    //依次重写next方法,返回不同的迭代器。

    private final class ValueIterator extends HashIterator<V> {
        public V next() {
            return nextEntry().value;
        }
    }

    private final class KeyIterator extends HashIterator<K> {
        public K next() {
            return nextEntry().getKey();
        }
    }

    private final class EntryIterator extends HashIterator<Map.Entry<K, V>> {
        public Map.Entry<K, V> next() {
            return nextEntry();
        }
    }

    // Subclass overrides these to alter behavior of views' iterator() method
    Iterator<K> newKeyIterator() {
        return new KeyIterator();
    }

    Iterator<V> newValueIterator() {
        return new ValueIterator();
    }

    Iterator<Map.Entry<K, V>> newEntryIterator() {
        return new EntryIterator();
    }

    // Views

    private transient Set<Map.Entry<K, V>> entrySet = null;

    /**
     * 返回一个key集。
     * 此Set集合只在第一次调用keySet()时被创建,此后返回的都是同一个Set。 
     * 此方法不是线程安全的,大量线程多次调用此方法返回的可能不是同一个Set(可能是重新new的)
     * 
     * 对map的修改会反应到Set当中,相反,对Set中key进行移除操作,比如 
     * Iterator.remove,Set.remove ,removeAll,retainAll,clear等操作时被移除的键 
     * 和它相关联的值也将从map中被移除,但是此Set不支持任何添加操作 
     */
    public Set<K> keySet() {
        Set<K> ks = keySet;
        return (ks != null ? ks : (keySet = new KeySet()));
    }

    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);
        }

        /**
         * 重写了Set的remove方法,
         * 父类remove都是调用迭代器的remove方法
         * */
        public boolean remove(Object o) {
            return HashMap.this.removeEntryForKey(o) != null;
        }

        public void clear() {
            HashMap.this.clear();
        }
    }

    /**
     * 同上
     */
    public Collection<V> values() {
        Collection<V> vs = values;
        return (vs != null ? vs : (values = new Values()));
    }

    private final class Values extends AbstractCollection<V> {
        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();
        }
    }

    /**
     * 同上
     */
    public Set<Map.Entry<K, V>> entrySet() {
        return entrySet0();
    }

    private Set<Map.Entry<K, V>> entrySet0() {
        Set<Map.Entry<K, V>> es = entrySet;
        return es != null ? es : (entrySet = new EntrySet());
    }

    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();
        }
    }

    /**
     * 序列化hashMap对象
     */
    private void writeObject(java.io.ObjectOutputStream s) throws IOException {
        Iterator<Map.Entry<K, V>> i = (size > 0) ? entrySet0().iterator()
                : null;

        // 写入默认信息
        s.defaultWriteObject();

        // 写入可以存储的容量
        s.writeInt(table.length);

        // 写入实际长度
        s.writeInt(size);

        // 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;

    /**
     * 读出HashMap对象
     */
    private void readObject(java.io.ObjectInputStream s) throws IOException,
            ClassNotFoundException {
        //读出默认信息
        s.defaultReadObject();

        // 读容量
        int numBuckets = s.readInt();
        table = new Entry[numBuckets];

        init(); // Give subclass a chance to do its thing.

        // 读长度
        int size = s.readInt();

        //读键值对,并还原HashMap元素
        for (int i = 0; i < size; i++) {
            K key = (K) s.readObject();
            V value = (V) s.readObject();
            putForCreate(key, value);
        }
    }

    // These methods are used when serializing HashSets
    int capacity() {
        return table.length;
    }

    float loadFactor() {
        return loadFactor;
    }
}

(四)HashSet

/**
 * 散列集(hashSet),就是不存在重复元素的集合。
 * HashSet是在HashMap的基础上实现的,
 * 以HashSet的元素做Key值使其值不会重复
 * */
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable,
        java.io.Serializable {
    static final long serialVersionUID = -5024744406713321676L;

    private transient HashMap<E, Object> map;


    //以Object作为虚假的Value值
    private static final Object PRESENT = new Object();

    /**
     * 
     * 构造一个新的,空Set集;
     * 实际是构造一个默认初始容量为16,加载因子为0.75的空HashMap
     */
    public HashSet() {
        map = new HashMap<E, Object>();
    }

    /**
     *
     * 构造一个包含指定集合c中所有元素的新的Set集。
     * 实际是构造包含集合c中所有元素的HashMap.
     * 初始大小必须大于容量*0.75
     * 
     */
    public HashSet(Collection<? extends E> c) {
        map = new HashMap<E, Object>(Math.max((int) (c.size() / .75f) + 1, 16));
        addAll(c);
    }

    /**
     * 以指定初始容量和加载因子构造HashMap
     */
    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<E, Object>(initialCapacity, loadFactor);
    }

    /**
     * 以初始容量构造HashMap
     */
    public HashSet(int initialCapacity) {
        map = new HashMap<E, Object>(initialCapacity);
    }

    /**
     * 
     * 构造一个Linked hash set.
     * 以指定初始容量,加载因子构造LinkedHashMap,dummy只是为了区别其他构造方法
     * 
     */
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<E, Object>(initialCapacity, loadFactor);
    }

    /**
     * 获得HashMap的键集迭代器
     */
    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

    /**
     * 返回元素个数
     */
    public int size() {
        return map.size();
    }

    /**
     * 判断Hash集是否为空
     */
    public boolean isEmpty() {
        return map.isEmpty();
    }

    /**
     * 如果Map中含有此key则返回true
     */
    public boolean contains(Object o) {
        return map.containsKey(o);
    }

    /**
     * 
     * 如果e不存在于Set中则添加e到集合,
     * 如果Map中key集不存在e,则添加并返回null,否则替换原来的value,返回oldValue
     *
     */
    public boolean add(E e) {
        return map.put(e, PRESENT) == null;
    }

    /**
     * 移除指定元素
     */
    public boolean remove(Object o) {
        return map.remove(o) == PRESENT;
    }

    /**
     * 清空map
     */
    public void clear() {
        map.clear();
    }

    /**
     * 返回HashSet的浅拷贝对象
     */
    public Object clone() {
        try {
            HashSet<E> newSet = (HashSet<E>) super.clone();
            newSet.map = (HashMap<E, Object>) map.clone();  
            return newSet;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }


    private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
        // Write out any hidden serialization magic
        s.defaultWriteObject();

        //写入HashMap的容量和加载系数
        s.writeInt(map.capacity());
        s.writeFloat(map.loadFactor());

        //写入size
        s.writeInt(map.size());

        //依次写入键值
        for (Iterator i = map.keySet().iterator(); i.hasNext();)
            s.writeObject(i.next());
    }


    private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
        // Read in any hidden serialization magic
        s.defaultReadObject();

        //读取容量和加载因子构造HashMap
        int capacity = s.readInt();
        float loadFactor = s.readFloat();
        //判断是LinkedHashMap还是HashMap
        map = (((HashSet) this) instanceof LinkedHashSet ? new LinkedHashMap<E, Object>(
                capacity, loadFactor)
                : new HashMap<E, Object>(capacity, loadFactor));

        // 读size
        int size = s.readInt();

        //依次读出所有元素
        for (int i = 0; i < size; i++) {
            E e = (E) s.readObject();
            map.put(e, PRESENT);
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值