• Java集合类源码分析


    常用类及源码分析

    集合类 原理分析
    Collection  
    List  
    Vector

    扩充容量的方法 ensureCapacityHelper
    很多方法都加入了synchronized同步语句,来保证线程安全
    Vector中也允许元素为null
    Vector现在已经基本不再使用

    ArrayList  

    ArrayList是基于数组实现 
    不是线程安全的,只能用在单线程环境下
    可以通过下标索引直接查找到指定位置的元素,因此查找效率高,但每次插入或删除元素,就要大量地移动元素,插入删除元素的效率低
    允许元素为null

    LinkedList  

    LinkedList是基于双向循环链表实现的,除了可以当做链表来操作外,它还可以当做栈、队列和双端队列来使用
    非线程安全的,只在单线程下适合使用
    LinkedList中允许元素为null
    插入删除效率高,查找效率低

    Set  同Collection
    HashSet  通过Map中的HashMap实现
    TreeSet  通过Map中的TreeMap实现
    Map  
    Hashtable  

    Hashtable同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。
    HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。
    Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。
    Hashtable也是JDK1.0引入的类,是线程安全的,能用于多线程环境中
    Hashtable中key和value都不允许为null,而HashMap中key和value都允许为null(key只能有一个为null,而value则可以有多个为null)。

    Properties  
    HashMap  

    HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长
    HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的ConcurrentHashMap。
    HashMap中key和value都允许为null。

    TreeMap  

    TreeMap是基于红黑树实现 红黑树是一种特殊的二叉排序树
    TreeMap是根据key进行排序的,它的排序和定位需要依赖比较器或覆写Comparable接口,也因此不需要key覆写hashCode方法和equals方法
    就可以排除掉重复的key,而HashMap的key则需要通过覆写hashCode方法和equals方法来确保没有重复的key。
    TreeMap的查询、插入、删除效率均没有HashMap高,一般只有要对key排序时才使用TreeMap。
    TreeMap的key不能为null,而HashMap的key可以为null

    public interface Collection <E> extends Iterable<E> {
        //1添加
        boolean add(E e);
        boolean addAll(Collection<? extends E> c);
        //2删除
        boolean remove(Object o);
        boolean removeAll(Collection<?> c);
        void clear();
        //3判断
        boolean contains(Object o);
        boolean containsAll(Collection<?> c);
        boolean isEmpty(); //集合是否为空
        //4获取
        int size();
        Iterator<E> iterator(); //迭代器 取出元素方式
        //5其它
        boolean retainAll(Collection<?> c); //取交集
        Object[] toArray(); //转数组
        <T> T[] toArray(T[] a);
        
        boolean equals(Object o);
        int hashCode();
    }
    public interface Iterable<T> {
        Iterator<T> iterator(); //具体集合类返回一个迭代器
    }
    
    public interface Iterator<E> {
        boolean hasNext(); //是否还有下个元素
        E next(); //下一个元素
        void remove();
    }
    public interface List<E> extends Collection<E> {
        //其它方法与Collection中相同
        //1添加
        void add(int index, E element);
        boolean addAll(int index, Collection<? extends E> c);
        //2删除
        E remove(int index);
        //3修改
        E set(int index, E element);
        //4获取
        E get(int index);
        int indexOf(Object o);
        int lastIndexOf(Object o);
        List<E> subList(int fromIndex, int toIndex);
        
        ListIterator<E> listIterator();
        ListIterator<E> listIterator(int index);
    }
    public class Vector <E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
        protected Object[] elementData; //数据数组 
        protected int elementCount; //实际数据的数量
        protected int capacityIncrement; //容量增长系数
        private static final long serialVersionUID = -2767605614048989439L; //序列版本号
        
        //四个不同的构造方法
        // Vector构造函数。默认容量是10。
        public Vector() {
            this(10);
        }
        
        //指定Vector容量大小的构造函数
        public Vector(int initialCapacity) {
            this(initialCapacity, 0);
        }
        
        //指定Vector"容量大小"和"增长系数"的构造函数
        public Vector(int initialCapacity, int capacityIncrement) {
            super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
            this.elementData = new Object[initialCapacity];
            this.capacityIncrement = capacityIncrement;
        }
    
        // 指定集合的Vector构造函数
        public Vector(Collection<? extends E> c) {
            elementData = c.toArray();
            elementCount = elementData.length;
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
        }
        
        //1增
        // 在index位置处插入元素(obj)
        public synchronized void insertElementAt(E obj, int index) {
            modCount++;
            if (index > elementCount) {
                throw new ArrayIndexOutOfBoundsException(index
                                                         + " > " + elementCount);
            }
            ensureCapacityHelper(elementCount + 1);
            System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
            elementData[index] = obj;
            elementCount++;
        }
        
        // 将“元素obj”添加到Vector末尾
        public synchronized void addElement(E obj) {
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = obj;
        }
        
        // 将“元素e”添加到Vector最后。
        public synchronized boolean add(E e) {
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = e;
            return true;
        }
        
        // 在index位置添加元素element 
        public void add(int index, E element) {
            insertElementAt(element, index);
        }
        
        // 将集合c添加到Vector中   
        public synchronized boolean addAll(Collection<? extends E> c) {
            modCount++;
            Object[] a = c.toArray();
            int numNew = a.length;
            ensureCapacityHelper(elementCount + numNew);
            System.arraycopy(a, 0, elementData, elementCount, numNew);
            elementCount += numNew;
            return numNew != 0;
        }
        
        // 从index位置开始,将集合c添加到Vector中
        public synchronized boolean addAll(int index, Collection<? extends E> c) {
            modCount++;
            if (index < 0 || index > elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
    
            Object[] a = c.toArray();
            int numNew = a.length;
            ensureCapacityHelper(elementCount + numNew);
    
            int numMoved = elementCount - index;
            if (numMoved > 0)
                System.arraycopy(elementData, index, elementData, index + numNew,
                                 numMoved);
    
            System.arraycopy(a, 0, elementData, index, numNew);
            elementCount += numNew;
            return numNew != 0;
        }
    
        //2删
        // 删除index位置的元素 
        public synchronized void removeElementAt(int index) {
            modCount++;
            if (index >= elementCount) {
                throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                         elementCount);
            }
            else if (index < 0) {
                throw new ArrayIndexOutOfBoundsException(index);
            }
            int j = elementCount - index - 1;
            if (j > 0) {
                System.arraycopy(elementData, index + 1, elementData, index, j);
            }
            elementCount--;
            elementData[elementCount] = null;
        }
        
        // 在Vector中查找并删除元素obj 成功的话,返回true;否则,返回false。  
        public synchronized boolean removeElement(Object obj) {
            modCount++;
            int i = indexOf(obj);
            if (i >= 0) {
                removeElementAt(i);
                return true;
            }
            return false;
        }
    
        // 删除Vector中的全部元素 
        public synchronized void removeAllElements() {
            modCount++;
            for (int i = 0; i < elementCount; i++)
                elementData[i] = null;
    
            elementCount = 0;
        }
        
        // 删除Vector中的元素o 
        public boolean remove(Object o) {
            return removeElement(o);
        }
        
        // 删除index位置的元素,并返回index位置的原始值  
        public synchronized E remove(int index) {
            modCount++;
            if (index >= elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
            E oldValue = elementData(index);
    
            int numMoved = elementCount - index - 1;
            if (numMoved > 0)
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
            elementData[--elementCount] = null; 
    
            return oldValue;
        }
    
        // 清空Vector
        public void clear() {
            removeAllElements();
        }
        
        // 删除集合c的全部元素
        public synchronized boolean removeAll(Collection<?> c) {
            return super.removeAll(c);
        }
    
        // 删除“非集合c中的元素”  
        public synchronized boolean retainAll(Collection<?> c) {
            return super.retainAll(c);
        }
        
        // 删除Vector中fromIndex到toIndex的元素
        protected synchronized void removeRange(int fromIndex, int toIndex) {
            modCount++;
            int numMoved = elementCount - toIndex;
            System.arraycopy(elementData, toIndex, elementData, fromIndex,
                             numMoved);
    
            int newElementCount = elementCount - (toIndex-fromIndex);
            while (elementCount != newElementCount)
                elementData[--elementCount] = null;
        }
        
        //3改
        // 设置index位置的元素值为obj
        public synchronized void setElementAt(E obj, int index) {
            if (index >= elementCount) {
                throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                         elementCount);
            }
            elementData[index] = obj;
        }
        
        // 设置index位置的值为element。并返回index位置的原始值 
        public synchronized E set(int index, E element) {
            if (index >= elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
    
            E oldValue = elementData(index);
            elementData[index] = element;
            return oldValue;
        }
        
        //4查
        // 返回“Vector的实际大小”,即Vector中元素个数 
        public synchronized int size() {
            return elementCount;
        }
        
        // 判断Vector是否为空
        public synchronized boolean isEmpty() {
            return elementCount == 0;
        }
        
        // 返回“Vector中全部元素对应的Enumeration” 
        public Enumeration<E> elements() {
            return new Enumeration<E>() {
                int count = 0;
    
                public boolean hasMoreElements() {
                    return count < elementCount;
                }
    
                public E nextElement() {
                    synchronized (Vector.this) {
                        if (count < elementCount) {
                            return elementData(count++);
                        }
                    }
                    throw new NoSuchElementException("Vector Enumeration");
                }
            };
        }
        
        // 返回Vector中是否包含对象(o) 
        public boolean contains(Object o) {
            return indexOf(o, 0) >= 0;
        }
    
        // 查找并返回元素(o)在Vector中的索引值   
        public int indexOf(Object o) {
            return indexOf(o, 0);
        }
    
        // 从index位置开始向后查找元素(o) 若找到,则返回元素的索引值;否则,返回-1    
        public synchronized int indexOf(Object o, int index) {
            if (o == null) {
                for (int i = index ; i < elementCount ; i++)
                    if (elementData[i]==null)
                        return i;
            } else {
                for (int i = index ; i < elementCount ; i++)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }
    
        // 从后向前查找元素(o)。并返回元素的索引
        public synchronized int lastIndexOf(Object o) {
            return lastIndexOf(o, elementCount-1);
        }
    
        // 从后向前查找元素(o)。开始位置是从前向后的第index个数 若找到,则返回元素的“索引值”;否则,返回-1。  
        public synchronized int lastIndexOf(Object o, int index) {
            if (index >= elementCount)
                throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
    
            if (o == null) {
                for (int i = index; i >= 0; i--)
                    if (elementData[i]==null)
                        return i;
            } else {
                for (int i = index; i >= 0; i--)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }
    
        // 返回Vector中index位置的元素 若index越界,则抛出异常    
        public synchronized E elementAt(int index) {
            if (index >= elementCount) {
                throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
            }
            return elementData(index);
        }
    
        // 获取Vector中的第一个元素 若失败,则抛出异常!
        public synchronized E firstElement() {
            if (elementCount == 0) {
                throw new NoSuchElementException();
            }
            return elementData(0);
        }
    
        // 获取Vector中的最后一个元素 若失败,则抛出异常! 
        public synchronized E lastElement() {
            if (elementCount == 0) {
                throw new NoSuchElementException();
            }
            return elementData(elementCount - 1);
        }
        
        @SuppressWarnings("unchecked")
        E elementData(int index) {
            return (E) elementData[index];
        }
    
        // 获取index位置的元素   
        public synchronized E get(int index) {
            if (index >= elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
    
            return elementData(index);
        }
        
        // 返回Vector是否包含集合c  
        public synchronized boolean containsAll(Collection<?> c) {
            return super.containsAll(c);
        }
        
        // 获取Vector中fromIndex(包括)到toIndex(不包括)的子集
        public synchronized List<E> subList(int fromIndex, int toIndex) {
            return Collections.synchronizedList(super.subList(fromIndex, toIndex),
                                                this);
        }
        
        //5其它
        // 返回Object数组 
        public synchronized Object[] toArray() {
            return Arrays.copyOf(elementData, elementCount);
        }
    
        // 返回Vector的模板数组。所谓模板数组,即可以将T设为任意的数据类型    
        @SuppressWarnings("unchecked")
        public synchronized <T> T[] toArray(T[] a) {
            if (a.length < elementCount)
                return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
    
            System.arraycopy(elementData, 0, a, 0, elementCount);
    
            if (a.length > elementCount)
                a[elementCount] = null;
    
            return a;
        }
    
        // 将数组Vector的全部元素都拷贝到数组anArray中 
        public synchronized void copyInto(Object[] anArray) {
            System.arraycopy(elementData, 0, anArray, 0, elementCount);
        }
    
        // 将当前容量值设为实际元素个数    
        public synchronized void trimToSize() {
            modCount++;
            int oldCapacity = elementData.length;
            if (elementCount < oldCapacity) {
                elementData = Arrays.copyOf(elementData, elementCount);
            }
        }
        
        // 确定Vector的容量
        public synchronized void ensureCapacity(int minCapacity) {
            if (minCapacity > 0) {
                modCount++;
                ensureCapacityHelper(minCapacity);
            }
        }
        
        // 确认“Vector容量”的帮助函数 
        private void ensureCapacityHelper(int minCapacity) {
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
        // 当Vector的容量不足以容纳当前的全部元素,增加容量大小。    
        // 若 容量增量系数>0(即capacityIncrement>0),则将容量增大当capacityIncrement    
        // 否则,将容量增大一倍。    
        private void grow(int minCapacity) {
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                             capacityIncrement : oldCapacity);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
        }
    
        // 设置容量值为 newSize
        public synchronized void setSize(int newSize) {
            modCount++;
            if (newSize > elementCount) {
                ensureCapacityHelper(newSize);
            } else {
                for (int i = newSize ; i < elementCount ; i++) {
                    elementData[i] = null;
                }
            }
            elementCount = newSize;
        }
    
        // 返回“Vector的总的容量” 
        public synchronized int capacity() {
            return elementData.length;
        }
    
        public synchronized Object clone() {
            try {
                @SuppressWarnings("unchecked")
                    Vector<E> v = (Vector<E>) super.clone();
                v.elementData = Arrays.copyOf(elementData, elementCount);
                v.modCount = 0;
                return v;
            } catch (CloneNotSupportedException e) {
                throw new InternalError();
            }
        }
    
        public synchronized boolean equals(Object o) {
            return super.equals(o);
        }
    
        public synchronized int hashCode() {
            return super.hashCode();
        }
    
        public synchronized String toString() {
            return super.toString();
        }
    
        //写入函数
        private void writeObject(java.io.ObjectOutputStream s)
                throws java.io.IOException {
            final java.io.ObjectOutputStream.PutField fields = s.putFields();
            final Object[] data;
            synchronized (this) {
                fields.put("capacityIncrement", capacityIncrement);
                fields.put("elementCount", elementCount);
                data = elementData.clone();
            }
            fields.put("elementData", data);
            s.writeFields();
        }
    
        public synchronized ListIterator<E> listIterator(int index) {
            if (index < 0 || index > elementCount)
                throw new IndexOutOfBoundsException("Index: "+index);
            return new ListItr(index);
        }
    
        public synchronized ListIterator<E> listIterator() {
            return new ListItr(0);
        }
    
        public synchronized Iterator<E> iterator() {
            return new Itr();
        }
    
        private class Itr implements Iterator<E> {
            int cursor;       // index of next element to return
            int lastRet = -1; // index of last element returned; -1 if no such
            int expectedModCount = modCount;
    
            public boolean hasNext() {
                return cursor != elementCount;
            }
    
            public E next() {
                synchronized (Vector.this) {
                    checkForComodification();
                    int i = cursor;
                    if (i >= elementCount)
                        throw new NoSuchElementException();
                    cursor = i + 1;
                    return elementData(lastRet = i);
                }
            }
    
            public void remove() {
                if (lastRet == -1)
                    throw new IllegalStateException();
                synchronized (Vector.this) {
                    checkForComodification();
                    Vector.this.remove(lastRet);
                    expectedModCount = modCount;
                }
                cursor = lastRet;
                lastRet = -1;
            }
    
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
    
        final class ListItr extends Itr implements ListIterator<E> {
            ListItr(int index) {
                super();
                cursor = index;
            }
    
            public boolean hasPrevious() {
                return cursor != 0;
            }
    
            public int nextIndex() {
                return cursor;
            }
    
            public int previousIndex() {
                return cursor - 1;
            }
    
            public E previous() {
                synchronized (Vector.this) {
                    checkForComodification();
                    int i = cursor - 1;
                    if (i < 0)
                        throw new NoSuchElementException();
                    cursor = i;
                    return elementData(lastRet = i);
                }
            }
    
            public void set(E e) {
                if (lastRet == -1)
                    throw new IllegalStateException();
                synchronized (Vector.this) {
                    checkForComodification();
                    Vector.this.set(lastRet, e);
                }
            }
    
            public void add(E e) {
                int i = cursor;
                synchronized (Vector.this) {
                    checkForComodification();
                    Vector.this.add(i, e);
                    expectedModCount = modCount;
                }
                cursor = i + 1;
                lastRet = -1;
            }
        }
    }
    public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable{
        transient int size = 0; //LinkedList中元素个数 
        transient Node<E> first; //链表的表头
        transient Node<E> last; ////链表的末尾
        
        // 默认构造函数:创建一个空的链表
        public LinkedList() {
        }
    
        //创建一个包含“集合”的LinkedList 
        public LinkedList(Collection<? extends E> c) {
            this();
            addAll(c);
        }
        
        //1增
        // 将元素添加到LinkedList的起始位置
        private void linkFirst(E e) {
            final Node<E> f = first;
            final Node<E> newNode = new Node<>(null, e, f);
            first = newNode;
            if (f == null)
                last = newNode;
            else
                f.prev = newNode;
            size++;
            modCount++;
        }
        
        // 将元素添加到LinkedList的结束位置 
        void linkLast(E e) {
            final Node<E> l = last;
            final Node<E> newNode = new Node<>(l, e, null);
            last = newNode;
            if (l == null)
                first = newNode;
            else
                l.next = newNode;
            size++;
            modCount++;
        }
        
        void linkBefore(E e, Node<E> succ) {
            final Node<E> pred = succ.prev;
            final Node<E> newNode = new Node<>(pred, e, succ);
            succ.prev = newNode;
            if (pred == null)
                first = newNode;
            else
                pred.next = newNode;
            size++;
            modCount++;
        }
        
        // 将元素添加到LinkedList的起始位置
        public void addFirst(E e) {
            linkFirst(e);
        }
    
        // 将元素添加到LinkedList的结束位置 
        public void addLast(E e) {
            linkLast(e);
        }
        
        // 将元素(E)添加到LinkedList结束位置 
        public boolean add(E e) {
            linkLast(e);
            return true;
        }
        
        //从双向链表的末尾开始,将“集合(c)”添加到双向链表中
        public boolean addAll(Collection<? extends E> c) {
            return addAll(size, c);
        }
    
        //从双向链表的index开始,将“集合(c)”添加到双向链表中
        public boolean addAll(int index, Collection<? extends E> c) {
            checkPositionIndex(index);
    
            Object[] a = c.toArray();
            int numNew = a.length;
            if (numNew == 0)
                return false;
    
            Node<E> pred, succ;
            if (index == size) {
                succ = null;
                pred = last;
            } else {
                succ = node(index);
                pred = succ.prev;
            }
    
            for (Object o : a) {
                @SuppressWarnings("unchecked") E e = (E) o;
                Node<E> newNode = new Node<>(pred, e, null);
                if (pred == null)
                    first = newNode;
                else
                    pred.next = newNode;
                pred = newNode;
            }
    
            if (succ == null) {
                last = pred;
            } else {
                pred.next = succ;
                succ.prev = pred;
            }
    
            size += numNew;
            modCount++;
            return true;
        }
        
        // 在index前添加节点,且节点的值为element
        public void add(int index, E element) {
            checkPositionIndex(index);
    
            if (index == size)
                linkLast(element);
            else
                linkBefore(element, node(index));
        }
        
        // 将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;
        }
        
        // 将e插入到双向链表开头 
        public void push(E e) {
            addFirst(e);
        }
        
        //2删
        
        private E unlinkFirst(Node<E> f) {
            final E element = f.item;
            final Node<E> next = f.next;
            f.item = null;
            f.next = null; 
            first = next;
            if (next == null)
                last = null;
            else
                next.prev = null;
            size--;
            modCount++;
            return element;
        }
    
        private E unlinkLast(Node<E> l) {
            final E element = l.item;
            final Node<E> prev = l.prev;
            l.item = null;
            l.prev = null; 
            last = prev;
            if (prev == null)
                first = null;
            else
                prev.next = null;
            size--;
            modCount++;
            return element;
        }
    
        E unlink(Node<E> x) {
            final E element = x.item;
            final Node<E> next = x.next;
            final Node<E> prev = x.prev;
    
            if (prev == null) {
                first = next;
            } else {
                prev.next = next;
                x.prev = null;
            }
    
            if (next == null) {
                last = prev;
            } else {
                next.prev = prev;
                x.next = null;
            }
    
            x.item = null;
            size--;
            modCount++;
            return element;
        }
        
        // 删除LinkedList的第一个元素
        public E removeFirst() {
            final Node<E> f = first;
            if (f == null)
                throw new NoSuchElementException();
            return unlinkFirst(f);
        }
    
        // 删除LinkedList的最后一个元素 
        public E removeLast() {
            final Node<E> l = last;
            if (l == null)
                throw new NoSuchElementException();
            return unlinkLast(l);
        }
        
        // 从LinkedList中删除元素(o)   从链表开始查找,如存在元素(o)则删除该元素并返回true 否则,返回false。 
        public boolean remove(Object o) {
            if (o == null) {
                for (Node<E> x = first; x != null; x = x.next) {
                    if (x.item == null) {
                        unlink(x);
                        return true;
                    }
                }
            } else {
                for (Node<E> x = first; x != null; x = x.next) {
                    if (o.equals(x.item)) {
                        unlink(x);
                        return true;
                    }
                }
            }
            return false;
        }
        
        // 清空双向链表 
        public void clear() {
            for (Node<E> x = first; x != null; ) {
                // 从表头开始,逐个向后遍历;对遍历到的节点执行一下操作:    
                // 设置前一个节点为null     
                // 设置当前节点的内容为null     
                // 设置后一个节点为“新的当前节点”  
                Node<E> next = x.next;
                x.item = null;
                x.next = null;
                x.prev = null;
                x = next;
            }
            first = last = null;
            size = 0;
            modCount++;
        }
        
        // 删除index位置的节点  
        public E remove(int index) {
            checkElementIndex(index);
            return unlink(node(index));
        }
        
        // 删除并返回第一个节点  若LinkedList的大小为0,则返回null 
        public E poll() {
            final Node<E> f = first;
            return (f == null) ? null : unlinkFirst(f);
        }
        
        // 删除并返回第一个节点 若LinkedList的大小为0,则返回null 
        public E pollFirst() {
            final Node<E> f = first;
            return (f == null) ? null : unlinkFirst(f);
        }
     
        // 删除并返回最后一个节点  若LinkedList的大小为0,则返回null 
        public E pollLast() {
            final Node<E> l = last;
            return (l == null) ? null : unlinkLast(l);
        }
        
        // 删除并返回第一个节点 
        public E pop() {
            return removeFirst();
        }
        
        // 从LinkedList开始向后查找,删除第一个值为元素(o)的节点
        public boolean removeFirstOccurrence(Object o) {
            return remove(o);
        }
    
        // 从LinkedList末尾向前查找,删除第一个值为元素(o)的节点 
        public boolean removeLastOccurrence(Object o) {
            if (o == null) {
                for (Node<E> x = last; x != null; x = x.prev) {
                    if (x.item == null) {
                        unlink(x);
                        return true;
                    }
                }
            } else {
                for (Node<E> x = last; x != null; x = x.prev) {
                    if (o.equals(x.item)) {
                        unlink(x);
                        return true;
                    }
                }
            }
            return false;
        }
        
        public E remove() {
            return removeFirst();
        }
        
        //3改
        // 设置index位置对应的节点的值为element 
        public E set(int index, E element) {
            checkElementIndex(index);
            Node<E> x = node(index);
            E oldVal = x.item;
            x.item = element;
            return oldVal;
        }
        
        //4查
        // 获取LinkedList的第一个元素 
        public E getFirst() {
            final Node<E> f = first;
            if (f == null)
                throw new NoSuchElementException();
            return f.item;
        }
        
        // 获取LinkedList的最后一个元素
        public E getLast() {
            final Node<E> l = last;
            if (l == null)
                throw new NoSuchElementException();
            return l.item;
        }
        
        // 判断LinkedList是否包含元素(o) 
        public boolean contains(Object o) {
            return indexOf(o) != -1;
        }
        
        // 返回LinkedList的大小
        public int size() {
            return size;
        }
        
        // 返回LinkedList指定位置的元素   
        public E get(int index) {
            checkElementIndex(index);
            return node(index).item;
        }
        
        // 获取双向链表中指定位置的节点  
        Node<E> node(int index) {
            // 获取index处的节点。    
            // 若index < 双向链表长度的1/2,则从前先后查找;    
            // 否则,从后向前查找。    
            if (index < (size >> 1)) {
                Node<E> x = first;
                for (int i = 0; i < index; i++)
                    x = x.next;
                return x;
            } else {
                Node<E> x = last;
                for (int i = size - 1; i > index; i--)
                    x = x.prev;
                return x;
            }
        }
        
        // 从前向后查找,返回“值为对象(o)的节点对应的索引”    不存在就返回-1   
        public int indexOf(Object o) {
            int index = 0;
            if (o == null) {
                for (Node<E> x = first; x != null; x = x.next) {
                    if (x.item == null)
                        return index;
                    index++;
                }
            } else {
                for (Node<E> x = first; x != null; x = x.next) {
                    if (o.equals(x.item))
                        return index;
                    index++;
                }
            }
            return -1;
        }
    
        // 从后向前查找,返回“值为对象(o)的节点对应的索引”   不存在就返回-1 
        public int lastIndexOf(Object o) {
            int index = size;
            if (o == null) {
                for (Node<E> x = last; x != null; x = x.prev) {
                    index--;
                    if (x.item == null)
                        return index;
                }
            } else {
                for (Node<E> x = last; x != null; x = x.prev) {
                    index--;
                    if (o.equals(x.item))
                        return index;
                }
            }
            return -1;
        }
        
        // 返回第一个节点  若LinkedList的大小为0,则返回null   
        public E peek() {
            final Node<E> f = first;
            return (f == null) ? null : f.item;
        }
        
        // 返回第一个节点   若LinkedList的大小为0,则抛出异常
        public E element() {
            return getFirst();
        }
        
        // 返回第一个节点 若LinkedList的大小为0,则返回null 
        public E peekFirst() {
            final Node<E> f = first;
            return (f == null) ? null : f.item;
         }
    
        // 返回最后一个节点  若LinkedList的大小为0,则返回null 
        public E peekLast() {
            final Node<E> l = last;
            return (l == null) ? null : l.item;
        }
        
        //5其它
        private boolean isElementIndex(int index) {
            return index >= 0 && index < size;
        }
    
        private boolean isPositionIndex(int index) {
            return index >= 0 && index <= size;
        }
    
        private String outOfBoundsMsg(int index) {
            return "Index: "+index+", Size: "+size;
        }
    
        private void checkElementIndex(int index) {
            if (!isElementIndex(index))
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    
        private void checkPositionIndex(int index) {
            if (!isPositionIndex(index))
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    
        public ListIterator<E> listIterator(int index) {
            checkPositionIndex(index);
            return new ListItr(index);
        }
    
        // List迭代器
        private class ListItr implements ListIterator<E> {
            private Node<E> lastReturned = null;
            private Node<E> next;
            private int nextIndex;
            private int expectedModCount = modCount;
    
            ListItr(int index) {
                next = (index == size) ? null : node(index);
                nextIndex = index;
            }
    
            public boolean hasNext() {
                return nextIndex < size;
            }
    
            public E next() {
                checkForComodification();
                if (!hasNext())
                    throw new NoSuchElementException();
    
                lastReturned = next;
                next = next.next;
                nextIndex++;
                return lastReturned.item;
            }
    
            public boolean hasPrevious() {
                return nextIndex > 0;
            }
    
            public E previous() {
                checkForComodification();
                if (!hasPrevious())
                    throw new NoSuchElementException();
    
                lastReturned = next = (next == null) ? last : next.prev;
                nextIndex--;
                return lastReturned.item;
            }
    
            public int nextIndex() {
                return nextIndex;
            }
    
            public int previousIndex() {
                return nextIndex - 1;
            }
    
            public void remove() {
                checkForComodification();
                if (lastReturned == null)
                    throw new IllegalStateException();
    
                Node<E> lastNext = lastReturned.next;
                unlink(lastReturned);
                if (next == lastReturned)
                    next = lastNext;
                else
                    nextIndex--;
                lastReturned = null;
                expectedModCount++;
            }
    
            public void set(E e) {
                if (lastReturned == null)
                    throw new IllegalStateException();
                checkForComodification();
                lastReturned.item = e;
            }
    
            public void add(E e) {
                checkForComodification();
                lastReturned = null;
                if (next == null)
                    linkLast(e);
                else
                    linkBefore(e, next);
                nextIndex++;
                expectedModCount++;
            }
    
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
    
        // 双向链表的节点所对应的数据结构 包含3部分:上一节点,下一节点,当前节点值
        private static class Node<E> {
            E item; //当前节点所包含的值
            Node<E> next; // 下一个节点   
            Node<E> prev; //上一个节点
    
            Node(Node<E> prev, E element, Node<E> next) {
                this.item = element;
                this.next = next;
                this.prev = prev;
            }
        }
    
        // 反向迭代器 
        public Iterator<E> descendingIterator() {
            return new DescendingIterator();
        }
    
        private class DescendingIterator implements Iterator<E> {
            private final ListItr itr = new ListItr(size());
            public boolean hasNext() {
                return itr.hasPrevious();
            }
            public E next() {
                return itr.previous();
            }
            public void remove() {
                itr.remove();
            }
        }
    
        @SuppressWarnings("unchecked")
        private LinkedList<E> superClone() {
            try {
                return (LinkedList<E>) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new InternalError();
            }
        }
    
        public Object clone() {
            LinkedList<E> clone = superClone();
    
            clone.first = clone.last = null;
            clone.size = 0;
            clone.modCount = 0;
    
            for (Node<E> x = first; x != null; x = x.next)
                clone.add(x.item);
    
            return clone;
        }
    
        public Object[] toArray() {
            Object[] result = new Object[size];
            int i = 0;
            for (Node<E> x = first; x != null; x = x.next)
                result[i++] = x.item;
            return result;
        }
    
        @SuppressWarnings("unchecked")
        public <T> T[] toArray(T[] a) {
            if (a.length < size)
                a = (T[])java.lang.reflect.Array.newInstance(
                                    a.getClass().getComponentType(), size);
            int i = 0;
            Object[] result = a;
            for (Node<E> x = first; x != null; x = x.next)
                result[i++] = x.item;
    
            if (a.length > size)
                a[size] = null;
    
            return a;
        }
    
        private static final long serialVersionUID = 876323262645176354L;
    
        private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
            // Write out any hidden serialization magic
            s.defaultWriteObject();
    
            // Write out size
            s.writeInt(size);
    
            // Write out all elements in the proper order.
            for (Node<E> x = first; x != null; x = x.next)
                s.writeObject(x.item);
        }
    
        @SuppressWarnings("unchecked")
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            // Read in any hidden serialization magic
            s.defaultReadObject();
    
            // Read in size
            int size = s.readInt();
    
            // Read in all elements in the proper order.
            for (int i = 0; i < size; i++)
                linkLast((E)s.readObject());
        }
    }
    
    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
        private static final long serialVersionUID = 8683452581122892189L; // 序列版本号 
        private static final int DEFAULT_CAPACITY = 10;
        private static final Object[] EMPTY_ELEMENTDATA = {}; 
        private transient Object[] elementData; //保存数据数组
        private int size; // ArrayList中实际数据的数量    
    
        // ArrayList无参构造函数。默认容量是10。
        public ArrayList() {
            super();
            this.elementData = EMPTY_ELEMENTDATA;
        }
        
        // ArrayList带容量大小的构造函数。 
        public ArrayList(int initialCapacity) {
            super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            this.elementData = new Object[initialCapacity];
        }
    
        // 创建一个包含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);
        }
        
        //1增
        // 将e添加到ArrayList中
        public boolean add(E e) {
            ensureCapacityInternal(size + 1); 
            elementData[size++] = e;
            return true;
        }
        
        // 将e添加到ArrayList的指定位置  
        public void add(int index, E element) {
            rangeCheckForAdd(index);
    
            ensureCapacityInternal(size + 1); 
            System.arraycopy(elementData, index, elementData, index + 1,
                             size - index);
            elementData[index] = element;
            size++;
        }
        
        // 将集合c追加到ArrayList中 
        public boolean addAll(Collection<? extends E> c) {
            Object[] a = c.toArray();
            int numNew = a.length;
            ensureCapacityInternal(size + numNew);  
            System.arraycopy(a, 0, elementData, size, numNew);
            size += numNew;
            return numNew != 0;
        }
     
        // 从index位置开始,将集合c添加到ArrayList   
        public boolean addAll(int index, Collection<? extends E> c) {
            rangeCheckForAdd(index);
    
            Object[] a = c.toArray();
            int numNew = a.length;
            ensureCapacityInternal(size + numNew); 
    
            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;
        }
        
        //2删
        // 删除ArrayList指定位置的元素   
        public E remove(int index) {
            rangeCheck(index);
    
            modCount++;
            E oldValue = elementData(index);
    
            int numMoved = size - index - 1;
            if (numMoved > 0)
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
            elementData[--size] = null;  
            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;
            if (numMoved > 0)
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
            elementData[--size] = null;  
        }
    
        // 清空ArrayList,将全部的元素设为null
        public void clear() {
            modCount++;
    
            for (int i = 0; i < size; i++)
                elementData[i] = null;
    
            size = 0;
        }
        
        // 删除fromIndex到toIndex之间的全部元素
        protected void removeRange(int fromIndex, int toIndex) {
            modCount++;
            int numMoved = size - toIndex;
            System.arraycopy(elementData, toIndex, elementData, fromIndex,
                             numMoved);
    
            int newSize = size - (toIndex-fromIndex);
            for (int i = newSize; i < size; i++) {
                elementData[i] = null;
            }
            size = newSize;
        }
        
        //3改
        // 设置index位置的值为element
        public E set(int index, E element) {
            rangeCheck(index);
    
            E oldValue = elementData(index);
            elementData[index] = element;
            return oldValue;
        }
        
        
        //4查
        // 返回ArrayList的实际大小 
        public int size() {
            return size;
        }
        
        //返回ArrayList是否为空 
        public boolean isEmpty() {
            return size == 0;
        }
        
        // ArrayList是否包含Object(o)
        public boolean contains(Object o) {
            return indexOf(o) >= 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;
        }
        
        // 反向查找,返回元素的索引值
        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;
        }
        
        // 获取index位置的元素值
        @SuppressWarnings("unchecked")
        E elementData(int index) {
            return (E) elementData[index];
        }
    
        public E get(int index) {
            rangeCheck(index);
            return elementData(index);
        }
        
        //5其它
        public Object[] toArray() {
            return Arrays.copyOf(elementData, size);
        }
    
        @SuppressWarnings("unchecked")
        public <T> T[] toArray(T[] a) {
            if (a.length < size)
                return (T[]) Arrays.copyOf(elementData, size, a.getClass());
            System.arraycopy(elementData, 0, a, 0, size);
            if (a.length > size)
                a[size] = null;
            return a;
        }
    
        // 将当前容量值设为实际元素个数
        public void trimToSize() {
            modCount++;
            if (size < elementData.length) {
                elementData = Arrays.copyOf(elementData, size);
            }
        }
    
        public void ensureCapacity(int minCapacity) {
            int minExpand = (elementData != EMPTY_ELEMENTDATA)
                ? 0
                : DEFAULT_CAPACITY;
    
            if (minCapacity > minExpand) {
                ensureExplicitCapacity(minCapacity);
            }
        }
    
        private void ensureCapacityInternal(int minCapacity) {
            if (elementData == EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
    
            ensureExplicitCapacity(minCapacity);
        }
    
        // 确定ArrarList的容量
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
        private void grow(int minCapacity) {
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) 
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
        }
    
        public Object clone() {
            try {
                @SuppressWarnings("unchecked")
                    ArrayList<E> v = (ArrayList<E>) super.clone();
                v.elementData = Arrays.copyOf(elementData, size);
                v.modCount = 0;
                return v;
            } catch (CloneNotSupportedException e) {
                throw new InternalError();
            }
        }
    
        private void rangeCheck(int index) {
            if (index >= size)
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    
        private void rangeCheckForAdd(int index) {
            if (index > size || index < 0)
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    
        private String outOfBoundsMsg(int index) {
            return "Index: "+index+", Size: "+size;
        }
    
        public boolean removeAll(Collection<?> c) {
            return batchRemove(c, false);
        }
    
        public boolean retainAll(Collection<?> c) {
            return batchRemove(c, true);
        }
    
        private boolean batchRemove(Collection<?> c, boolean complement) {
            final Object[] elementData = this.elementData;
            int r = 0, w = 0;
            boolean modified = false;
            try {
                for (; r < size; r++)
                    if (c.contains(elementData[r]) == complement)
                        elementData[w++] = elementData[r];
            } finally {
                if (r != size) {
                    System.arraycopy(elementData, r,
                                     elementData, w,
                                     size - r);
                    w += size - r;
                }
                if (w != size) {
                    for (int i = w; i < size; i++)
                        elementData[i] = null;
                    modCount += size - w;
                    size = w;
                    modified = true;
                }
            }
            return modified;
        }
    
        private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException{
            int expectedModCount = modCount;
            s.defaultWriteObject();
    
            s.writeInt(size);
    
            for (int i=0; i<size; i++) {
                s.writeObject(elementData[i]);
            }
    
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
        }
    
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            elementData = EMPTY_ELEMENTDATA;
    
            s.defaultReadObject();
            s.readInt(); 
    
            if (size > 0) {
                ensureCapacityInternal(size);
    
                Object[] a = elementData;
                for (int i=0; i<size; i++) {
                    a[i] = s.readObject();
                }
            }
        }
    
        public ListIterator<E> listIterator(int index) {
            if (index < 0 || index > size)
                throw new IndexOutOfBoundsException("Index: "+index);
            return new ListItr(index);
        }
    
        public ListIterator<E> listIterator() {
            return new ListItr(0);
        }
    
        public Iterator<E> iterator() {
            return new Itr();
        }
    
        private class Itr implements Iterator<E> {
            int cursor; 
            int lastRet = -1;  
            int expectedModCount = modCount;
    
            public boolean hasNext() {
                return cursor != size;
            }
    
            @SuppressWarnings("unchecked")
            public E next() {
                checkForComodification();
                int i = cursor;
                if (i >= size)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i + 1;
                return (E) elementData[lastRet = i];
            }
    
            public void remove() {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();
    
                try {
                    ArrayList.this.remove(lastRet);
                    cursor = lastRet;
                    lastRet = -1;
                    expectedModCount = modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }
    
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
    
        private class ListItr extends Itr implements ListIterator<E> {
            ListItr(int index) {
                super();
                cursor = index;
            }
    
            public boolean hasPrevious() {
                return cursor != 0;
            }
    
            public int nextIndex() {
                return cursor;
            }
    
            public int previousIndex() {
                return cursor - 1;
            }
    
            @SuppressWarnings("unchecked")
            public E previous() {
                checkForComodification();
                int i = cursor - 1;
                if (i < 0)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i;
                return (E) elementData[lastRet = i];
            }
    
            public void set(E e) {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();
    
                try {
                    ArrayList.this.set(lastRet, e);
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }
    
            public void add(E e) {
                checkForComodification();
    
                try {
                    int i = cursor;
                    ArrayList.this.add(i, e);
                    cursor = i + 1;
                    lastRet = -1;
                    expectedModCount = modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }
        }
    
        public List<E> subList(int fromIndex, int toIndex) {
            subListRangeCheck(fromIndex, toIndex, size);
            return new SubList(this, 0, fromIndex, toIndex);
        }
    
        static void subListRangeCheck(int fromIndex, int toIndex, int size) {
            if (fromIndex < 0)
                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
            if (toIndex > size)
                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
            if (fromIndex > toIndex)
                throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                                   ") > toIndex(" + toIndex + ")");
        }
    
        private class SubList extends AbstractList<E> implements RandomAccess {
            private final AbstractList<E> parent;
            private final int parentOffset;
            private final int offset;
            int size;
    
            SubList(AbstractList<E> parent,
                    int offset, int fromIndex, int toIndex) {
                this.parent = parent;
                this.parentOffset = fromIndex;
                this.offset = offset + fromIndex;
                this.size = toIndex - fromIndex;
                this.modCount = ArrayList.this.modCount;
            }
    
            public E set(int index, E e) {
                rangeCheck(index);
                checkForComodification();
                E oldValue = ArrayList.this.elementData(offset + index);
                ArrayList.this.elementData[offset + index] = e;
                return oldValue;
            }
    
            public E get(int index) {
                rangeCheck(index);
                checkForComodification();
                return ArrayList.this.elementData(offset + index);
            }
    
            public int size() {
                checkForComodification();
                return this.size;
            }
    
            public void add(int index, E e) {
                rangeCheckForAdd(index);
                checkForComodification();
                parent.add(parentOffset + index, e);
                this.modCount = parent.modCount;
                this.size++;
            }
    
            public E remove(int index) {
                rangeCheck(index);
                checkForComodification();
                E result = parent.remove(parentOffset + index);
                this.modCount = parent.modCount;
                this.size--;
                return result;
            }
    
            protected void removeRange(int fromIndex, int toIndex) {
                checkForComodification();
                parent.removeRange(parentOffset + fromIndex,
                                   parentOffset + toIndex);
                this.modCount = parent.modCount;
                this.size -= toIndex - fromIndex;
            }
    
            public boolean addAll(Collection<? extends E> c) {
                return addAll(this.size, c);
            }
    
            public boolean addAll(int index, Collection<? extends E> c) {
                rangeCheckForAdd(index);
                int cSize = c.size();
                if (cSize==0)
                    return false;
    
                checkForComodification();
                parent.addAll(parentOffset + index, c);
                this.modCount = parent.modCount;
                this.size += cSize;
                return true;
            }
    
            public Iterator<E> iterator() {
                return listIterator();
            }
    
            public ListIterator<E> listIterator(final int index) {
                checkForComodification();
                rangeCheckForAdd(index);
                final int offset = this.offset;
    
                return new ListIterator<E>() {
                    int cursor = index;
                    int lastRet = -1;
                    int expectedModCount = ArrayList.this.modCount;
    
                    public boolean hasNext() {
                        return cursor != SubList.this.size;
                    }
    
                    @SuppressWarnings("unchecked")
                    public E next() {
                        checkForComodification();
                        int i = cursor;
                        if (i >= SubList.this.size)
                            throw new NoSuchElementException();
                        Object[] elementData = ArrayList.this.elementData;
                        if (offset + i >= elementData.length)
                            throw new ConcurrentModificationException();
                        cursor = i + 1;
                        return (E) elementData[offset + (lastRet = i)];
                    }
    
                    public boolean hasPrevious() {
                        return cursor != 0;
                    }
    
                    @SuppressWarnings("unchecked")
                    public E previous() {
                        checkForComodification();
                        int i = cursor - 1;
                        if (i < 0)
                            throw new NoSuchElementException();
                        Object[] elementData = ArrayList.this.elementData;
                        if (offset + i >= elementData.length)
                            throw new ConcurrentModificationException();
                        cursor = i;
                        return (E) elementData[offset + (lastRet = i)];
                    }
    
                    public int nextIndex() {
                        return cursor;
                    }
    
                    public int previousIndex() {
                        return cursor - 1;
                    }
    
                    public void remove() {
                        if (lastRet < 0)
                            throw new IllegalStateException();
                        checkForComodification();
    
                        try {
                            SubList.this.remove(lastRet);
                            cursor = lastRet;
                            lastRet = -1;
                            expectedModCount = ArrayList.this.modCount;
                        } catch (IndexOutOfBoundsException ex) {
                            throw new ConcurrentModificationException();
                        }
                    }
    
                    public void set(E e) {
                        if (lastRet < 0)
                            throw new IllegalStateException();
                        checkForComodification();
    
                        try {
                            ArrayList.this.set(offset + lastRet, e);
                        } catch (IndexOutOfBoundsException ex) {
                            throw new ConcurrentModificationException();
                        }
                    }
    
                    public void add(E e) {
                        checkForComodification();
    
                        try {
                            int i = cursor;
                            SubList.this.add(i, e);
                            cursor = i + 1;
                            lastRet = -1;
                            expectedModCount = ArrayList.this.modCount;
                        } catch (IndexOutOfBoundsException ex) {
                            throw new ConcurrentModificationException();
                        }
                    }
    
                    final void checkForComodification() {
                        if (expectedModCount != ArrayList.this.modCount)
                            throw new ConcurrentModificationException();
                    }
                };
            }
    
            public List<E> subList(int fromIndex, int toIndex) {
                subListRangeCheck(fromIndex, toIndex, size);
                return new SubList(this, offset, fromIndex, toIndex);
            }
    
            private void rangeCheck(int index) {
                if (index < 0 || index >= this.size)
                    throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
            }
    
            private void rangeCheckForAdd(int index) {
                if (index < 0 || index > this.size)
                    throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
            }
    
            private String outOfBoundsMsg(int index) {
                return "Index: "+index+", Size: "+this.size;
            }
    
            private void checkForComodification() {
                if (ArrayList.this.modCount != this.modCount)
                    throw new ConcurrentModificationException();
            }
        }
    }
    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;
        private static final Object PRESENT = new Object();
    
        public HashSet() {
            map = new HashMap<>();
        }
    
        public HashSet(Collection<? extends E> c) {
            map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
            addAll(c);
        }
    
        public HashSet(int initialCapacity, float loadFactor) {
            map = new HashMap<>(initialCapacity, loadFactor);
        }
    
        public HashSet(int initialCapacity) {
            map = new HashMap<>(initialCapacity);
        }
    
        HashSet(int initialCapacity, float loadFactor, boolean dummy) {
            map = new LinkedHashMap<>(initialCapacity, loadFactor);
        }
        
        //1增
        public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
        
        //2删
        public boolean remove(Object o) {
            return map.remove(o)==PRESENT;
        }
        
        public void clear() {
            map.clear();
        }
        
        //3改
        
        //4查
        public int size() {
            return map.size();
        }
    
        public boolean isEmpty() {
            return map.isEmpty();
        }
    
        public boolean contains(Object o) {
            return map.containsKey(o);
        }
        
        public Iterator<E> iterator() {
            return map.keySet().iterator();
        }
        
        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 {
            s.defaultWriteObject();
    
            s.writeInt(map.capacity());
            s.writeFloat(map.loadFactor());
    
            s.writeInt(map.size());
    
            for (E e : map.keySet())
                s.writeObject(e);
        }
    
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            s.defaultReadObject();
    
            int capacity = s.readInt();
            float loadFactor = s.readFloat();
            map = (((HashSet)this) instanceof LinkedHashSet ?
                   new LinkedHashMap<E,Object>(capacity, loadFactor) :
                   new HashMap<E,Object>(capacity, loadFactor));
    
            int size = s.readInt();
    
            for (int i=0; i<size; i++) {
                E e = (E) s.readObject();
                map.put(e, PRESENT);
            }
        }
    }
    public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable{
        private transient NavigableMap<E,Object> m;
        private static final Object PRESENT = new Object();
    
        TreeSet(NavigableMap<E,Object> m) {
            this.m = m;
        }
    
        public TreeSet() {
            this(new TreeMap<E,Object>());
        }
    
        public TreeSet(Comparator<? super E> comparator) {
            this(new TreeMap<>(comparator));
        }
    
        public TreeSet(Collection<? extends E> c) {
            this();
            addAll(c);
        }
    
        public TreeSet(SortedSet<E> s) {
            this(s.comparator());
            addAll(s);
        }
    
        public Iterator<E> iterator() {
            return m.navigableKeySet().iterator();
        }
    
        public Iterator<E> descendingIterator() {
            return m.descendingKeySet().iterator();
        }
    
        public NavigableSet<E> descendingSet() {
            return new TreeSet<>(m.descendingMap());
        }
    
        public int size() {
            return m.size();
        }
    
        public boolean isEmpty() {
            return m.isEmpty();
        }
    
        public boolean contains(Object o) {
            return m.containsKey(o);
        }
    
        public boolean add(E e) {
            return m.put(e, PRESENT)==null;
        }
    
        public boolean remove(Object o) {
            return m.remove(o)==PRESENT;
        }
    
        public void clear() {
            m.clear();
        }
    
        public  boolean addAll(Collection<? extends E> c) {
            if (m.size()==0 && c.size() > 0 &&
                c instanceof SortedSet &&
                m instanceof TreeMap) {
                SortedSet<? extends E> set = (SortedSet<? extends E>) c;
                TreeMap<E,Object> map = (TreeMap<E, Object>) m;
                Comparator<? super E> cc = (Comparator<? super E>) set.comparator();
                Comparator<? super E> mc = map.comparator();
                if (cc==mc || (cc != null && cc.equals(mc))) {
                    map.addAllForTreeSet(set, PRESENT);
                    return true;
                }
            }
            return super.addAll(c);
        }
    
        public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
                                      E toElement,   boolean toInclusive) {
            return new TreeSet<>(m.subMap(fromElement, fromInclusive,
                                           toElement,   toInclusive));
        }
    
        public NavigableSet<E> headSet(E toElement, boolean inclusive) {
            return new TreeSet<>(m.headMap(toElement, inclusive));
        }
    
        public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
            return new TreeSet<>(m.tailMap(fromElement, inclusive));
        }
    
        public SortedSet<E> subSet(E fromElement, E toElement) {
            return subSet(fromElement, true, toElement, false);
        }
    
        public SortedSet<E> headSet(E toElement) {
            return headSet(toElement, false);
        }
    
        public SortedSet<E> tailSet(E fromElement) {
            return tailSet(fromElement, true);
        }
    
        public Comparator<? super E> comparator() {
            return m.comparator();
        }
    
        public E first() {
            return m.firstKey();
        }
    
        public E last() {
            return m.lastKey();
        }
    
        public E lower(E e) {
            return m.lowerKey(e);
        }
    
        public E floor(E e) {
            return m.floorKey(e);
        }
    
        public E ceiling(E e) {
            return m.ceilingKey(e);
        }
    
        public E higher(E e) {
            return m.higherKey(e);
        }
    
        public E pollFirst() {
            Map.Entry<E,?> e = m.pollFirstEntry();
            return (e == null) ? null : e.getKey();
        }
    
        public E pollLast() {
            Map.Entry<E,?> e = m.pollLastEntry();
            return (e == null) ? null : e.getKey();
        }
    
        public Object clone() {
            TreeSet<E> clone = null;
            try {
                clone = (TreeSet<E>) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new InternalError();
            }
    
            clone.m = new TreeMap<>(m);
            return clone;
        }
    
        private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
            s.defaultWriteObject();
            s.writeObject(m.comparator());
            s.writeInt(m.size());
            for (E e : m.keySet())
                s.writeObject(e);
        }
    
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            s.defaultReadObject();
    
            Comparator<? super E> c = (Comparator<? super E>) s.readObject();
    
            TreeMap<E,Object> tm;
            if (c==null)
                tm = new TreeMap<>();
            else
                tm = new TreeMap<>(c);
            m = tm;
    
            int size = s.readInt();
    
            tm.readTreeSet(size, s, PRESENT);
        }
    
        private static final long serialVersionUID = -2479143000061671589L;
    }
    public interface Map<K,V> {
        //1增
        V put(K key, V value);//返回前一个和key关联的值,如果没有返回null.
        
        //2删
        void clear(); //清空map集合
        V remove(Object key); //根据指定的key删除这个键值对
        
        //3改
        
        //4查
        boolean isEmpty();
        boolean containsKey(Object key);
        boolean containsValue(Object value);
        int size();
        V get(Object key);
        
        void putAll(Map<? extends K, ? extends V> m);
        Set<K> keySet();
        Collection<V> values();
        Set<Map.Entry<K, V>> entrySet();
        interface Entry<K,V> {
            K getKey();
            V getValue();
            V setValue(V value);
            boolean equals(Object o);
            int hashCode();
        }
        
        boolean equals(Object o);
        int hashCode();
    
    }
    public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {
        static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;   // 默认的初始容量(容量为HashMap中槽的数目)是16,且实际容量必须是2的整数次幂。
        static final int MAXIMUM_CAPACITY = 1 << 30; // 最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换)  
        static final float DEFAULT_LOAD_FACTOR = 0.75f; // 默认加载因子为0.75   
        static final Entry<?,?>[] EMPTY_TABLE = {}; 
        transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE; // 存储数据的Entry数组 每一个Entry本质上是一个单向链表
        transient int size; // HashMap的底层数组中已用槽的数量
        int threshold; // HashMap的阈值,用于判断是否需要调整HashMap的容量(threshold = 容量*加载因子)
        final float loadFactor; // 加载因子实际大小 
        transient int modCount; // HashMap被改变的次数    
        static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = Integer.MAX_VALUE;
    
        private static class Holder {
    
            static final int ALTERNATIVE_HASHING_THRESHOLD;
    
            static {
                String altThreshold = java.security.AccessController.doPrivileged(
                    new sun.security.action.GetPropertyAction(
                        "jdk.map.althashing.threshold"));
    
                int threshold;
                try {
                    threshold = (null != altThreshold)
                            ? Integer.parseInt(altThreshold)
                            : ALTERNATIVE_HASHING_THRESHOLD_DEFAULT;
    
                    if (threshold == -1) {
                        threshold = Integer.MAX_VALUE;
                    }
    
                    if (threshold < 0) {
                        throw new IllegalArgumentException("value must be positive integer.");
                    }
                } catch(IllegalArgumentException failed) {
                    throw new Error("Illegal value for 'jdk.map.althashing.threshold'", failed);
                }
    
                ALTERNATIVE_HASHING_THRESHOLD = threshold;
            }
        }
    
        transient int hashSeed = 0;
    
        // 指定“容量大小”和“加载因子”的构造函数 
        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);
    
            this.loadFactor = loadFactor;
            threshold = initialCapacity;
            init();
        }
    
        // 指定“容量大小”的构造函数 
        public HashMap(int initialCapacity) {
            this(initialCapacity, DEFAULT_LOAD_FACTOR);
        }
    
        // 默认构造函数
        public HashMap() {
            this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
        }
    
        // 包含“子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);
            inflateTable(threshold);
            putAllForCreate(m);
        }
    
        private static int roundUpToPowerOf2(int number) {
            return number >= MAXIMUM_CAPACITY
                    ? MAXIMUM_CAPACITY
                    : (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1;
        }
    
        private void inflateTable(int toSize) {
            int capacity = roundUpToPowerOf2(toSize);
    
            threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
            table = new Entry[capacity];
            initHashSeedAsNeeded(capacity);
        }
    
        void init() {
        }
    
        final boolean initHashSeedAsNeeded(int capacity) {
            boolean currentAltHashing = hashSeed != 0;
            boolean useAltHashing = sun.misc.VM.isBooted() &&
                    (capacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD);
            boolean switching = currentAltHashing ^ useAltHashing;
            if (switching) {
                hashSeed = useAltHashing
                    ? sun.misc.Hashing.randomHashSeed(this)
                    : 0;
            }
            return switching;
        }
        
        //求hash值的方法,重新计算hash值 
        final int hash(Object k) {
            int h = hashSeed;
            if (0 != h && k instanceof String) {
                return sun.misc.Hashing.stringHash32((String) k);
            }
    
            h ^= k.hashCode();
            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();
            Entry<K,V> entry = getEntry(key);
    
            return null == entry ? null : entry.getValue();
        }
    
        // 获取“key为null”的元素的值    
        // HashMap将“key为null”的元素存储在table[0]位置,但不一定是该链表的第一个位置!  
        private V getForNullKey() {
            if (size == 0) {
                return null;
            }
            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) {
            if (size == 0) {
                return null;
            }
            // 获取key的hash值 
            int hash = (key == null) ? 0 : hash(key);
            // 在“该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 != null && key.equals(k))))
                    return e;
            }
            return null;
        }
    
        // 将“key-value”添加到HashMap中   
        public V put(K key, V value) {
            if (table == EMPTY_TABLE) {
                inflateTable(threshold);
            }
            // 若“key为null”,则将该键值对添加到table[0]中。  
            if (key == null)
                return putForNullKey(value);
            // 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。
            int hash = hash(key);
            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);
                    return oldValue;
                }
            }
    
            modCount++;
            //将key-value添加到table[i]处  
            addEntry(hash, key, value, i);
            return null;
        }
    
        //将“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;
                }
            }
            modCount++;
            addEntry(0, null, value, 0);
            return null;
        }
    
        // 创建HashMap对应的“添加方法”,    
        // 它和put()不同。putForCreate()是内部方法,它被构造函数等调用,用来创建HashMap    
        // 而put()是对外提供的往HashMap中添加元素的方法。 
        private void putForCreate(K key, V value) {
            int hash = null == key ? 0 : hash(key);
            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 != null && key.equals(k)))) {
                    e.value = value;
                    return;
                }
            }
    
            createEntry(hash, key, value, i);
        }
    
        // 将“m”中的全部元素都添加到HashMap中。    
        // 该方法被内部的构造HashMap的方法所调用。   
        private void putAllForCreate(Map<? extends K, ? extends V> m) {
            for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
                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, initHashSeedAsNeeded(newCapacity));
            table = newTable;
            threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
        }
    
        // 将HashMap中的全部元素都添加到newTable中 
        void transfer(Entry[] newTable, boolean rehash) {
            int newCapacity = newTable.length;
            for (Entry<K,V> e : table) {
                while(null != e) {
                    Entry<K,V> next = e.next;
                    if (rehash) {
                        e.hash = null == e.key ? 0 : hash(e.key);
                    }
                    int i = indexFor(e.hash, newCapacity);
                    e.next = newTable[i];
                    newTable[i] = e;
                    e = next;
                }
            }
        }
    
        // 将"m"的全部元素都添加到HashMap中
        public void putAll(Map<? extends K, ? extends V> m) {
            int numKeysToBeAdded = m.size();
            if (numKeysToBeAdded == 0)
                return;
    
            if (table == EMPTY_TABLE) {
                inflateTable((int) Math.max(numKeysToBeAdded * loadFactor, threshold));
            }
    
            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 (Map.Entry<? extends K, ? extends V> e : m.entrySet())
                put(e.getKey(), e.getValue());
        }
    
        // 删除“键为key”元素 
        public V remove(Object key) {
            Entry<K,V> e = removeEntryForKey(key);
            return (e == null ? null : e.value);
        }
    
        final Entry<K,V> removeEntryForKey(Object key) {
            if (size == 0) {
                return null;
            }
            // 获取哈希值。若key为null,则哈希值为0;否则调用hash()进行计算 
            int hash = (key == null) ? 0 : hash(key);
            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 (size == 0 || !(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);
            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;
        }
    
        // 清空HashMap,将所有的元素设为null  
        public void clear() {
            modCount++;
            Arrays.fill(table, 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;
        }
    
        // 是否包含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) {
            }
            if (result.table != EMPTY_TABLE) {
                result.inflateTable(Math.min(
                    (int) Math.min(
                        size * Math.min(1 / loadFactor, 4.0f),
                        HashMap.MAXIMUM_CAPACITY),
                   table.length));
            }
            result.entrySet = null;
            result.modCount = 0;
            result.size = 0;
            result.init();
            result.putAllForCreate(this);
    
            return result;
        }
    
        // Entry是单向链表 它是 “HashMap链式存储法”对应的链表。  
        static class Entry<K,V> implements Map.Entry<K,V> {
            final K key;
            V value;
            Entry<K,V> next; // 指向下一个节点 
            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;
            }
    
            public final int hashCode() {
                return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
            }
    
            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) {
            if ((size >= threshold) && (null != table[bucketIndex])) {
                resize(2 * table.length);
                hash = (null != key) ? hash(key) : 0;
                bucketIndex = indexFor(hash, table.length);
            }
    
            createEntry(hash, key, value, bucketIndex);
        }
    
        // 创建Entry。将“key-value”插入指定位置
        void createEntry(int hash, K key, V value, int bucketIndex) {
            Entry<K,V> e = table[bucketIndex];
            table[bucketIndex] = new Entry<>(hash, key, value, e);
            size++;
        }
    
        // HashIterator是HashMap迭代器的抽象出来的父类,实现了公共函数
        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;
                    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();
    
                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;
            }
        }
    
        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();
            }
        }
    
        Iterator<K> newKeyIterator()   {
            return new KeyIterator();
        }
        Iterator<V> newValueIterator()   {
            return new ValueIterator();
        }
        Iterator<Map.Entry<K,V>> newEntryIterator()   {
            return new EntryIterator();
        }
    
        private transient Set<Map.Entry<K,V>> entrySet = null;
    
        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 {
            s.defaultWriteObject();
            if (table==EMPTY_TABLE) {
                s.writeInt(roundUpToPowerOf2(threshold));
            } else {
               s.writeInt(table.length);
            }
            s.writeInt(size);
            if (size > 0) {
                for(Map.Entry<K,V> e : entrySet0()) {
                    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 {
            s.defaultReadObject();
            if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
                throw new InvalidObjectException("Illegal load factor: " +
                                                   loadFactor);
            }
    
            table = (Entry<K,V>[]) EMPTY_TABLE;
    
            s.readInt(); // ignored.
    
            int mappings = s.readInt();
            if (mappings < 0)
                throw new InvalidObjectException("Illegal mappings count: " +
                                                   mappings);
    
            int capacity = (int) Math.min(
                        mappings * Math.min(1 / loadFactor, 4.0f),
                        HashMap.MAXIMUM_CAPACITY);
    
            if (mappings > 0) {
                inflateTable(capacity);
            } else {
                threshold = capacity;
            }
    
            init(); 
    
            for (int i = 0; i < mappings; 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;   }
    }
    public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable {
    
        private transient Entry<?,?>[] table; //保存key-value的数组 Hashtable同样采用单链表解决冲突,每一个Entry本质上是一个单向链表
        private transient int count; //键值对的数量
        private int threshold; //阈值,用于判断是否需要调整Hashtable的容量(threshold = 容量*加载因子)
        private float loadFactor; //加载因子
        private transient int modCount = 0; //Hashtable被改变的次数,用于fail-fast机制的实现
        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)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
        }
    
        // 指定“容量大小”的构造函数
        public Hashtable(int initialCapacity) {
            this(initialCapacity, 0.75f);
        }
    
        // 默认构造函数 容量大小是11;加载因子是0.75
        public Hashtable() {
            this(11, 0.75f);
        }
    
        // 包含“子Map”的构造函数
        public Hashtable(Map<? extends K, ? extends V> t) {
            this(Math.max(2*t.size(), 11), 0.75f);
            putAll(t);
        }
    
        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<?,?> 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<?,?> e = tab[index] ; e != null ; e = e.next) {
                if ((e.hash == hash) && e.key.equals(key)) {
                    return true;
                }
            }
            return false;
        }
    
        // 返回key对应的value,没有的话返回null
        @SuppressWarnings("unchecked")
        public synchronized V get(Object key) {
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
                if ((e.hash == hash) && e.key.equals(key)) {
                    return (V)e.value;
                }
            }
            return null;
        }
    
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
        //调整Hashtable的长度,将长度变成原来的2倍+1
        @SuppressWarnings("unchecked")
        protected void rehash() {
            int oldCapacity = table.length;
            Entry<?,?>[] oldMap = table;
    
            //创建新容量大小的Entry数组
            int newCapacity = (oldCapacity << 1) + 1;
            if (newCapacity - MAX_ARRAY_SIZE > 0) {
                if (oldCapacity == MAX_ARRAY_SIZE)
                    // Keep running with MAX_ARRAY_SIZE buckets
                    return;
                newCapacity = MAX_ARRAY_SIZE;
            }
            Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];
    
            modCount++;
            threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
            table = newMap;
    
            //将“旧的Hashtable”中的元素复制到“新的Hashtable”中
            for (int i = oldCapacity ; i-- > 0 ;) {
                for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {
                    Entry<K,V> e = old;
                    old = old.next;
    
                    int index = (e.hash & 0x7FFFFFFF) % newCapacity;
                    e.next = (Entry<K,V>)newMap[index];
                    newMap[index] = e;
                }
            }
        }
    
        private void addEntry(int hash, K key, V value, int index) {
            modCount++;
    
            Entry<?,?> tab[] = table;
            if (count >= threshold) {
                // Rehash the table if the threshold is exceeded
                rehash();
    
                tab = table;
                hash = key.hashCode();
                index = (hash & 0x7FFFFFFF) % tab.length;
            }
    
            // Creates the new entry.
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>) tab[index];
            tab[index] = new Entry<>(hash, key, value, e);
            count++;
        }
    
        // 将“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 = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> entry = (Entry<K,V>)tab[index];
            for(; entry != null ; entry = entry.next) {
                if ((entry.hash == hash) && entry.key.equals(key)) {
                    V old = entry.value;
                    entry.value = value;
                    return old;
                }
            }
    
            // 若“Hashtable中不存在键为key的键值对”,
            addEntry(hash, key, value, index);
            return null;
        }
    
        // 删除Hashtable中键为key的元素
        public synchronized V remove(Object key) {
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for(Entry<K,V> 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<?,?> t = (Hashtable<?,?>)super.clone();
                t.table = new Entry<?,?>[table.length];
                for (int i = table.length ; i-- > 0 ; ) {
                    t.table[i] = (table[i] != null)
                            ? (Entry<?,?>) table[i].clone() : null;
                }
                t.keySet = null;
                t.entrySet = null;
                t.values = null;
                t.modCount = 0;
                return t;
            } catch (CloneNotSupportedException e) {
                // this shouldn't happen, since we are Cloneable
                throw new InternalError(e);
            }
        }
    
        /**
         * Returns a string representation of this <tt>Hashtable</tt> object
         * in the form of a set of entries, enclosed in braces and separated
         * by the ASCII characters "<tt>,&nbsp;</tt>" (comma and space). Each
         * entry is rendered as the key, an equals sign <tt>=</tt>, and the
         * associated element, where the <tt>toString</tt> method is used to
         * convert the key and element to strings.
         *
         * @return  a string representation of this hashtable
         */
        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的枚举类对象
        private <T> Enumeration<T> getEnumeration(int type) {
            if (count == 0) {
                return Collections.emptyEnumeration();
            } else {
                return new Enumerator<>(type, false);
            }
        }
    
        // 获取Hashtable的迭代器
        private <T> Iterator<T> getIterator(int type) {
            if (count == 0) {
                return Collections.emptyIterator();
            } else {
                return new Enumerator<>(type, true);
            }
        }
    
        private transient volatile Set<K> keySet; // Hashtable的“key的集合”。它是一个Set,没有重复元素
        private transient volatile Set<Map.Entry<K,V>> entrySet; // Hashtable的“key-value的集合”。它是一个Set,没有重复元素
        private transient volatile Collection<V> values; // Hashtable的“key-value的集合”。它是一个Collection,可以有重复元素
    
        // 返回一个被synchronizedSet封装后的KeySet对象
        public Set<K> keySet() {
            if (keySet == null)
                keySet = Collections.synchronizedSet(new KeySet(), this);
            return keySet;
        }
    
        // Hashtable的Key的Set集合。
        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对象
        public Set<Map.Entry<K,V>> entrySet() {
            if (entrySet==null)
                entrySet = Collections.synchronizedSet(new EntrySet(), this);
            return entrySet;
        }
    
        // Hashtable的Entry的Set集合。
        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);
            }
    
            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 = key.hashCode();
                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;
            }
    
            public boolean remove(Object o) {
                if (!(o instanceof Map.Entry))
                    return false;
                Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
                Object key = entry.getKey();
                Entry<?,?>[] tab = table;
                int hash = key.hashCode();
                int index = (hash & 0x7FFFFFFF) % tab.length;
    
                @SuppressWarnings("unchecked")
                Entry<K,V> e = (Entry<K,V>)tab[index];
                for(Entry<K,V> 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对象
        public Collection<V> values() {
            if (values==null)
                values = Collections.synchronizedCollection(new ValueCollection(),
                        this);
            return values;
        }
    
        // Hashtable的value的Collection集合。
        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();
            }
        }
    
        public synchronized boolean equals(Object o) {
            if (o == this)
                return true;
    
            if (!(o instanceof Map))
                return false;
            Map<?,?> t = (Map<?,?>) o;
            if (t.size() != size())
                return false;
    
            try {
                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;
    
            loadFactor = -loadFactor;
            Entry<?,?>[] tab = table;
            for (Entry<?,?> entry : tab) {
                while (entry != null) {
                    h += entry.hashCode();
                    entry = entry.next;
                }
            }
    
            loadFactor = -loadFactor;
    
            return h;
        }
    
        @Override
        public synchronized V getOrDefault(Object key, V defaultValue) {
            V result = get(key);
            return (null == result) ? defaultValue : result;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public synchronized void forEach(BiConsumer<? super K, ? super V> action) {
            Objects.requireNonNull(action);     // explicit check required in case
            // table is empty.
            final int expectedModCount = modCount;
    
            Entry<?, ?>[] tab = table;
            for (Entry<?, ?> entry : tab) {
                while (entry != null) {
                    action.accept((K)entry.key, (V)entry.value);
                    entry = entry.next;
    
                    if (expectedModCount != modCount) {
                        throw new ConcurrentModificationException();
                    }
                }
            }
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public synchronized void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
            Objects.requireNonNull(function);     // explicit check required in case
            // table is empty.
            final int expectedModCount = modCount;
    
            Entry<K, V>[] tab = (Entry<K, V>[])table;
            for (Entry<K, V> entry : tab) {
                while (entry != null) {
                    entry.value = Objects.requireNonNull(
                            function.apply(entry.key, entry.value));
                    entry = entry.next;
    
                    if (expectedModCount != modCount) {
                        throw new ConcurrentModificationException();
                    }
                }
            }
        }
    
        @Override
        public synchronized V putIfAbsent(K key, V value) {
            Objects.requireNonNull(value);
    
            // Makes sure the key is not already in the hashtable.
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> entry = (Entry<K,V>)tab[index];
            for (; entry != null; entry = entry.next) {
                if ((entry.hash == hash) && entry.key.equals(key)) {
                    V old = entry.value;
                    if (old == null) {
                        entry.value = value;
                    }
                    return old;
                }
            }
    
            addEntry(hash, key, value, index);
            return null;
        }
    
        @Override
        public synchronized boolean remove(Object key, Object value) {
            Objects.requireNonNull(value);
    
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
                if ((e.hash == hash) && e.key.equals(key) && e.value.equals(value)) {
                    modCount++;
                    if (prev != null) {
                        prev.next = e.next;
                    } else {
                        tab[index] = e.next;
                    }
                    count--;
                    e.value = null;
                    return true;
                }
            }
            return false;
        }
    
        @Override
        public synchronized boolean replace(K key, V oldValue, V newValue) {
            Objects.requireNonNull(oldValue);
            Objects.requireNonNull(newValue);
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for (; e != null; e = e.next) {
                if ((e.hash == hash) && e.key.equals(key)) {
                    if (e.value.equals(oldValue)) {
                        e.value = newValue;
                        return true;
                    } else {
                        return false;
                    }
                }
            }
            return false;
        }
    
        @Override
        public synchronized V replace(K key, V value) {
            Objects.requireNonNull(value);
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for (; e != null; e = e.next) {
                if ((e.hash == hash) && e.key.equals(key)) {
                    V oldValue = e.value;
                    e.value = value;
                    return oldValue;
                }
            }
            return null;
        }
    
        @Override
        public synchronized V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
            Objects.requireNonNull(mappingFunction);
    
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for (; e != null; e = e.next) {
                if (e.hash == hash && e.key.equals(key)) {
                    // Hashtable not accept null value
                    return e.value;
                }
            }
    
            V newValue = mappingFunction.apply(key);
            if (newValue != null) {
                addEntry(hash, key, newValue, index);
            }
    
            return newValue;
        }
    
        @Override
        public synchronized V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            Objects.requireNonNull(remappingFunction);
    
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
                if (e.hash == hash && e.key.equals(key)) {
                    V newValue = remappingFunction.apply(key, e.value);
                    if (newValue == null) {
                        modCount++;
                        if (prev != null) {
                            prev.next = e.next;
                        } else {
                            tab[index] = e.next;
                        }
                        count--;
                    } else {
                        e.value = newValue;
                    }
                    return newValue;
                }
            }
            return null;
        }
    
        @Override
        public synchronized V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            Objects.requireNonNull(remappingFunction);
    
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
                if (e.hash == hash && Objects.equals(e.key, key)) {
                    V newValue = remappingFunction.apply(key, e.value);
                    if (newValue == null) {
                        modCount++;
                        if (prev != null) {
                            prev.next = e.next;
                        } else {
                            tab[index] = e.next;
                        }
                        count--;
                    } else {
                        e.value = newValue;
                    }
                    return newValue;
                }
            }
    
            V newValue = remappingFunction.apply(key, null);
            if (newValue != null) {
                addEntry(hash, key, newValue, index);
            }
    
            return newValue;
        }
    
        @Override
        public synchronized V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
            Objects.requireNonNull(remappingFunction);
    
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
                if (e.hash == hash && e.key.equals(key)) {
                    V newValue = remappingFunction.apply(e.value, value);
                    if (newValue == null) {
                        modCount++;
                        if (prev != null) {
                            prev.next = e.next;
                        } else {
                            tab[index] = e.next;
                        }
                        count--;
                    } else {
                        e.value = newValue;
                    }
                    return newValue;
                }
            }
    
            if (value != null) {
                addEntry(hash, key, value, index);
            }
    
            return value;
        }
    
        private void writeObject(java.io.ObjectOutputStream s)
                throws IOException {
            Entry<Object, Object> entryStack = null;
    
            synchronized (this) {
                // Write out the length, threshold, loadfactor
                s.defaultWriteObject();
    
                // Write out length, count of elements
                s.writeInt(table.length);
                s.writeInt(count);
    
                // Stack copies of the entries in the table
                for (int index = 0; index < table.length; index++) {
                    Entry<?,?> entry = table[index];
    
                    while (entry != null) {
                        entryStack =
                                new Entry<>(0, entry.key, entry.value, entryStack);
                        entry = entry.next;
                    }
                }
            }
    
            // Write out the key/value objects from the stacked entries
            while (entryStack != null) {
                s.writeObject(entryStack.key);
                s.writeObject(entryStack.value);
                entryStack = entryStack.next;
            }
        }
    
        private void readObject(java.io.ObjectInputStream s)
                throws IOException, ClassNotFoundException {
            s.defaultReadObject();
    
            int origlength = s.readInt();
            int elements = s.readInt();
            
            int length = (int)(elements * loadFactor) + (elements / 20) + 3;
            if (length > elements && (length & 1) == 0)
                length--;
            if (origlength > 0 && length > origlength)
                length = origlength;
            table = new Entry<?,?>[length];
            threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
            count = 0;
    
            // Read the number of elements and then all the key/value objects
            for (; elements > 0; elements--) {
                @SuppressWarnings("unchecked")
                K key = (K)s.readObject();
                @SuppressWarnings("unchecked")
                V value = (V)s.readObject();
                // synch could be eliminated for performance
                reconstitutionPut(table, key, value);
            }
        }
    
        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<?,?> 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.
            @SuppressWarnings("unchecked")
            Entry<K,V> e = (Entry<K,V>)tab[index];
            tab[index] = new Entry<>(hash, key, value, e);
            count++;
        }
    
        // Hashtable的Entry节点,它本质上是一个单向链表。
        private static class Entry<K,V> implements Map.Entry<K,V> {
            final int hash;
            final K key;
            V value;
            Entry<K,V> next;// 指向的下一个Entry,即链表的下一个节点
    
            protected Entry(int hash, K key, V value, Entry<K,V> next) {
                this.hash = hash;
                this.key =  key;
                this.value = value;
                this.next = next;
            }
    
            @SuppressWarnings("unchecked")
            protected Object clone() {
                return new Entry<>(hash, key, value,
                        (next==null ? null : (Entry<K,V>) next.clone()));
            }
    
            public K getKey() {
                return key;
            }
    
            public V getValue() {
                return value;
            }
    
            public V setValue(V value) {
                if (value == null)
                    throw new NullPointerException();
    
                V oldValue = this.value;
                this.value = value;
                return oldValue;
            }
    
            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 ^ Objects.hashCode(value);
            }
    
            public String toString() {
                return key.toString()+"="+value.toString();
            }
        }
    
        // Types of Enumerations/Iterations
        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> {
            Entry<?,?>[] table = Hashtable.this.table;
            int index = table.length;
            Entry<?,?> entry;
            Entry<?,?> lastReturned;
            int type;
    
            boolean iterator;
            protected int expectedModCount = modCount;// 在将Enumerator当作迭代器使用时会用到,用来实现fail-fast机制。   
    
            Enumerator(int type, boolean iterator) {
                this.type = type;
                this.iterator = iterator;
            }
    
            public boolean hasMoreElements() {
                Entry<?,?> 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;
            }
    
            @SuppressWarnings("unchecked")
            public T nextElement() {
                Entry<?,?> 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<?,?> 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 methods
            public boolean hasNext() {
                return hasMoreElements();
            }
    
            public T next() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                return nextElement();
            }
    
            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;
    
                    @SuppressWarnings("unchecked")
                    Entry<K,V> e = (Entry<K,V>)tab[index];
                    for(Entry<K,V> 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();
                }
            }
        }
    }

    集合类

    类名 实现思路
    ArrayList  
    LinkedList  
    Vector  
    HashMap  
    HashTable  
    LinkedHashMap  

    并发包concurrent

    类名 实现思路
    ConcurrentHashMap  
    AbstractQueuedSynchronizer  
    ReentrantLock  
  • 相关阅读:
    spring cloud eureka 服务端开启密码认证后,客户端无法接入问题
    微信小程序 获取用户信息 encryptData解密 C#版本
    Chrome浏览器离线安装 Postman 5.X 报错
    framework7使用问题汇总
    centos 6 防火墙开启端口无效问题
    ASP.NET下使用xml反序列化、缓存实现个性化配置文件的实时生效
    Swagger+SpringBoot整理
    baseController
    微信小程序-扫码点餐系统设计
    redis+Spring初级应用
  • 原文地址:https://www.cnblogs.com/huanyi0723/p/6171068.html
Copyright © 2020-2023  润新知