zoukankan      html  css  js  c++  java
  • Java源码学习(JDK 11)——java.lang.Collection

    Collection:接口

    Collection

    public interface Collection<E> extends Iterable<E> {
        // Query Operations
        int size();
        boolean isEmpty();
        boolean contains(Object o);
        Iterator<E> iterator();
        Object[] toArray();
        <T> T[] toArray(T[] a);
    
        default <T> T[] toArray(IntFunction<T[]> generator) {
            return toArray(generator.apply(0));
        }
    
        // Modification Operations
        boolean add(E e);
        boolean remove(Object o);
    
    
        // Bulk Operations
        boolean containsAll(Collection<?> c);
        boolean addAll(Collection<? extends E> c);
        boolean removeAll(Collection<?> c);
    
        default boolean removeIf(Predicate<? super E> filter) {
            Objects.requireNonNull(filter);
            boolean removed = false;
            final Iterator<E> each = iterator();
            while (each.hasNext()) {
                if (filter.test(each.next())) {
                    each.remove();
                    removed = true;
                }
            }
            return removed;
        }
    
        boolean retainAll(Collection<?> c);
        void clear();
    
    
        // Comparison and hashing
        boolean equals(Object o);
        int hashCode();
    
        @Override
        default Spliterator<E> spliterator() {
            return Spliterators.spliterator(this, 0);
        }
    
        default Stream<E> stream() {
            return StreamSupport.stream(spliterator(), false);
        }
    
        default Stream<E> parallelStream() {
            return StreamSupport.stream(spliterator(), true);
        }
    }
    
    
    • Collection 实现 Iterable 接口,具有 iterator() 方法,可以迭代。

    AbstractCollection

    public abstract class AbstractCollection<E> implements Collection<E> {
        protected AbstractCollection() {
        }
    
        // Query Operations
        public abstract Iterator<E> iterator();
        public abstract int size();
    
        public boolean isEmpty() {
            return size() == 0;
        }
    
        public boolean contains(Object o) {
            Iterator<E> it = iterator();
            if (o==null) {
                while (it.hasNext())
                    if (it.next()==null)
                        return true;
            } else {
                while (it.hasNext())
                    if (o.equals(it.next()))
                        return true;
            }
            return false;
        }
    
        public Object[] toArray() {
            // Estimate size of array; be prepared to see more or fewer elements
            Object[] r = new Object[size()];
            Iterator<E> it = iterator();
            for (int i = 0; i < r.length; i++) {
                if (! it.hasNext()) // fewer elements than expected
                    return Arrays.copyOf(r, i);
                r[i] = it.next();
            }
            return it.hasNext() ? finishToArray(r, it) : r;
        }
    
        @SuppressWarnings("unchecked")
        public <T> T[] toArray(T[] a) { /*...*/ }
    
    
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
        // 重新分配数组空间 供 toArray 方法使用
        @SuppressWarnings("unchecked")
        private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
            int i = r.length;
            while (it.hasNext()) {
                int cap = r.length;
                if (i == cap) {
                    int newCap = cap + (cap >> 1) + 1;	// 扩容大小 1.5 倍 + 1
                    // overflow-conscious code
                    if (newCap - MAX_ARRAY_SIZE > 0)
                        newCap = hugeCapacity(cap + 1);
                    r = Arrays.copyOf(r, newCap);
                }
                r[i++] = (T)it.next();
            }
            // trim if overallocated
            return (i == r.length) ? r : Arrays.copyOf(r, i);
        }
    
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError("Required array size too large");
            return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
        }
    
        // Modification Operations
    
        public boolean add(E e) {	// 支持 add 的 Collection 覆盖该方法 不支持的直接抛出异常
            throw new UnsupportedOperationException();
        }
    
        public boolean remove(Object o) {
            Iterator<E> it = iterator();
            if (o==null) {
                while (it.hasNext()) {
                    if (it.next()==null) {
                        it.remove();
                        return true;
                    }
                }
            } else {
                while (it.hasNext()) {
                    if (o.equals(it.next())) {
                        it.remove();
                        return true;
                    }
                }
            }
            return false;
        }
    
    
        // Bulk Operations
        public boolean containsAll(Collection<?> c) { /*...*/ }
    
        public boolean addAll(Collection<? extends E> c) { /*...*/ }
    
        public boolean removeAll(Collection<?> c) { /*...*/ }
    
        public boolean retainAll(Collection<?> c) { /*...*/ }
    
        public void clear() {
            Iterator<E> it = iterator();
            while (it.hasNext()) {
                it.next();
                it.remove();
            }
        }
    
        //  String conversion
        public String toString() { /*...*/ }
    }
    
    
    • AbstractCollection 提供了几乎所有方法的实现,各种操作基于 iterator() 抽象方法,因此子类只需要实现 iterator() 和 size() 方法,可修改的 Collection 需要提供 add 的实现。

    AbstractSet

    public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
    
        protected AbstractSet() {
        }
    
        // Comparison and hashing
    
        public boolean equals(Object o) {
            if (o == this)
                return true;
    
            if (!(o instanceof Set))
                return false;
            Collection<?> c = (Collection<?>) o;
            if (c.size() != size())
                return false;
            try {
                return containsAll(c);
            } catch (ClassCastException | NullPointerException unused) {
                return false;
            }
        }
    
        public int hashCode() { /*...*/ }
    
        public boolean removeAll(Collection<?> c) {
            Objects.requireNonNull(c);
            boolean modified = false;
    
            if (size() > c.size()) {
                for (Object e : c)
                    modified |= remove(e);
            } else {
                for (Iterator<?> i = iterator(); i.hasNext(); ) {
                    if (c.contains(i.next())) {
                        i.remove();
                        modified = true;
                    }
                }
            }
            return modified;
        }
    }
    
    • AbstractSet 覆盖了 hashCode 和 equals 方法,equals 利用 containsAll 来实现。

    • AbstractSet 覆盖了 removeAll 方法,对于容量较大的情况不需要使用迭代器。

    HashSet

    public class HashSet<E>
        extends AbstractSet<E>
        implements Set<E>, Cloneable, java.io.Serializable
    {
        static final long serialVersionUID = -5024744406713321676L;
    
        // HashSet 内部利用 HashMap 的 keySet() 来实现
        private transient HashMap<E,Object> map;
    
        // Dummy value to associate with an Object in the backing Map
        // 作为 Map 键值对里的 value
        private static final Object PRESENT = new Object();
    
        // default initial capacity (16) and load factor (0.75).
        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);
        }
    
        // 提供给 LinkedHashSet 使用
        HashSet(int initialCapacity, float loadFactor, boolean dummy) {
            map = new LinkedHashMap<>(initialCapacity, loadFactor);
        }
    
        public Iterator<E> iterator() {
            return map.keySet().iterator();
        }
    
        public int size() {
            return map.size();
        }
    
        public boolean isEmpty() {
            return map.isEmpty();
        }
    
        public boolean contains(Object o) {
            return map.containsKey(o);
        }
    
        public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
    
        public boolean remove(Object o) {
            return map.remove(o)==PRESENT;
        }
    
        public void clear() {
            map.clear();
        }
    
        @SuppressWarnings("unchecked")
        public Object clone() { /*...*/ }
    
        private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { /*...*/ }
    
        private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { /*...*/ }
    
        public Spliterator<E> spliterator() {
            return new HashMap.KeySpliterator<>(map, 0, -1, 0, 0);
        }
    }
    
    • HashSet 内部基于 HashMap 来实现,并覆盖了 add,remove 等方法以提高效率。

    LinkedHashSet

    public class LinkedHashSet<E>
        extends HashSet<E>
        implements Set<E>, Cloneable, java.io.Serializable {
    
        // 构造函数借助于 HashSet 中的 HashSet(int initialCapacity, float loadFactor, boolean dummy) 方法
        // 该方法实际创建了一个 LinkedHashMap
    
        public LinkedHashSet(Collection<? extends E> c) {
            super(Math.max(2*c.size(), 11), .75f, true);
            addAll(c);
        }
    
        @Override
        public Spliterator<E> spliterator() {
            return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
        }
    }
    
    • LinkedHashSet 几乎与 HashSet 完全一致,只是内部借助的是 LinkedHashMap

    • LinkedHashSet 维护了 插入顺序

    TreeSet

    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;
        }
    
        // 内部基于 TreeMap
        public TreeSet() {
            this(new TreeMap<>());
        }
    
        // 构造器
    
        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) {
            // Use linear-time version if applicable
            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<?> cc = 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(); }
    
        // NavigableSet API methods
    
        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();
        }
    
        @SuppressWarnings("unchecked")
        public Object clone() { /*...*/ }
    
        private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { /*...*/ }
    
        private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { /*...*/ }
    
        public Spliterator<E> spliterator() {
            return TreeMap.keySpliteratorFor(m);
        }
    
        private static final long serialVersionUID = -2479143000061671589L;
    }
    
    
    • TreeMap 与 HashMap 实现上区别不大,内部依托于 TreeMap,并实现了 NavigableSet 接口,提供了一系列有序性操作。

    • TreeMap 覆盖了 addAll 方法,如果两个有序 set 的比较器相同,可以用线性时间完成。

    AbstractList

    public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    
        protected AbstractList() {
        }
    
        public boolean add(E e) {
            add(size(), e);	// 在末尾插入
            return true;
        }
    
        public abstract E get(int index);
    
        public E set(int index, E element) {
            throw new UnsupportedOperationException();
        }
    
        public void add(int index, E element) {
            throw new UnsupportedOperationException();
        }
    
        public E remove(int index) {
            throw new UnsupportedOperationException();
        }
    
    
        // Search Operations
    
        public int indexOf(Object o) {
            ListIterator<E> it = listIterator();
            if (o==null) {
                while (it.hasNext())
                    if (it.next()==null)
                        return it.previousIndex();
            } else {
                while (it.hasNext())
                    if (o.equals(it.next()))
                        return it.previousIndex();
            }
            return -1;
        }
    
        public int lastIndexOf(Object o) { /*...*/ }	// 与 indexOf 类似 从后向前遍历
    
    
        // Bulk Operations
    
        public void clear() {
            removeRange(0, size());
        }
    
        public boolean addAll(int index, Collection<? extends E> c) {
            rangeCheckForAdd(index);
            boolean modified = false;
            for (E e : c) {
                add(index++, e);
                modified = true;
            }
            return modified;
        }
    
    
        // Iterators
        // 借助内部类来实现
        public Iterator<E> iterator() { return new Itr(); }
    
        public ListIterator<E> listIterator() { return listIterator(0); }
    
        public ListIterator<E> listIterator(final int index) {
            rangeCheckForAdd(index);
            return new ListItr(index);
        }
    
        private class Itr implements Iterator<E> {
            /**
             * Index of element to be returned by subsequent call to next.
             */
            int cursor = 0;
    
            /**
             * Index of element returned by most recent call to next or
             * previous.  Reset to -1 if this element is deleted by a call
             * to remove.
             */
            int lastRet = -1;
    
            /**
             * The modCount value that the iterator believes that the backing
             * List should have.  If this expectation is violated, the iterator
             * has detected concurrent modification.
             */
            int expectedModCount = modCount;
    
            public boolean hasNext() {
                return cursor != size();
            }
    
            public E next() {
                checkForComodification();
                try {
                    int i = cursor;
                    E next = get(i);
                    lastRet = i;
                    cursor = i + 1;
                    return next;
                } catch (IndexOutOfBoundsException e) {
                    checkForComodification();
                    throw new NoSuchElementException();
                }
            }
    
            public void remove() {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();
    
                try {
                    AbstractList.this.remove(lastRet);
                    if (lastRet < cursor)
                        cursor--;
                    lastRet = -1;
                    expectedModCount = modCount;
                } catch (IndexOutOfBoundsException e) {
                    throw new ConcurrentModificationException();
                }
            }
    
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
    
        private class ListItr extends Itr implements ListIterator<E> {
            ListItr(int index) {
                cursor = index;
            }
    
            public boolean hasPrevious() {
                return cursor != 0;
            }
    
            public E previous() {
                checkForComodification();
                try {
                    int i = cursor - 1;
                    E previous = get(i);
                    lastRet = cursor = i;
                    return previous;
                } catch (IndexOutOfBoundsException e) {
                    checkForComodification();
                    throw new NoSuchElementException();
                }
            }
    
            public int nextIndex() {
                return cursor;
            }
    
            public int previousIndex() {
                return cursor-1;
            }
    
            public void set(E e) {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();
    
                try {
                    AbstractList.this.set(lastRet, e);
                    expectedModCount = modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }
    
            public void add(E e) {
                checkForComodification();
    
                try {
                    int i = cursor;
                    AbstractList.this.add(i, e);
                    lastRet = -1;
                    cursor = i + 1;
                    expectedModCount = modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }
        }
    
        public List<E> subList(int fromIndex, int toIndex) { // 使用静态内部类实现
            subListRangeCheck(fromIndex, toIndex, size());
            return (this instanceof RandomAccess ? new RandomAccessSubList<>(this, fromIndex, toIndex) : new SubList<>(this, 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 + ")");
        }
    
        // Comparison and hashing
    
        public boolean equals(Object o) {
            if (o == this)
                return true;
            if (!(o instanceof List))
                return false;
    
            ListIterator<E> e1 = listIterator();
            ListIterator<?> e2 = ((List<?>) o).listIterator();
            while (e1.hasNext() && e2.hasNext()) {
                E o1 = e1.next();
                Object o2 = e2.next();
                if (!(o1==null ? o2==null : o1.equals(o2)))
                    return false;
            }
            return !(e1.hasNext() || e2.hasNext());
        }
    
        public int hashCode() { /*...*/ }
    
        protected void removeRange(int fromIndex, int toIndex) {
            ListIterator<E> it = listIterator(fromIndex);
            for (int i=0, n=toIndex-fromIndex; i<n; i++) {
                it.next();
                it.remove();
            }
        }
    
        // iterator 使用 modCount 值来判断在遍历的过程中是否发生了结构修改
        protected transient int modCount = 0;
    
        private void rangeCheckForAdd(int index) {
            if (index < 0 || index > size())
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    
        private String outOfBoundsMsg(int index) {
            return "Index: "+index+", Size: "+size();
        }
    
        static final class RandomAccessSpliterator<E> implements Spliterator<E> { /*...*/ }
    
        private static class SubList<E> extends AbstractList<E> { /*...*/ }
    
        private static class RandomAccessSubList<E> extends SubList<E> implements RandomAccess { /*...*/ }
    }
    
    
    • AbstractList 内部维护 modCount 来记录结构发生变化的次数,在遍历时,迭代器会判断 modCount 值是否一致,不一致说明出现了并发修改问题。

    • AbstractList 有 2 个内部类,Itr,和继承了 Itr 的 ListItr,分别对应 iterator() 和 listIterator() 方法。

    • Itr 内部维护 3 个整型变量

      • cursor:记录当前下标,用于遍历操作
      • lastRet:上一个遍历的下标,用于删除操作
      • expectedModCount:预期的 modCount 值,用于判断并发修改问题
    • Itr 的遍历操作是通过 get() 实现的。

    • ListItr 继承 Itr,提供双向的遍历和从某一下标开始的遍历。

    ArrayList

    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
        private static final long serialVersionUID = 8683452581122892189L;
    
        // 默认初始容量为 10
        private static final int DEFAULT_CAPACITY = 10;
    
        // 空 ArrayList 共享使用
        private static final Object[] EMPTY_ELEMENTDATA = {};
    
        // 使用默认构造器时使用
        private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    
        // 使用数组存储对象
        transient Object[] elementData; // non-private to simplify nested class access
    
        private int size; // 列表当前容量
    
        public ArrayList(int initialCapacity) {
            if (initialCapacity > 0) {
                this.elementData = new Object[initialCapacity];
            } else if (initialCapacity == 0) {
                this.elementData = EMPTY_ELEMENTDATA;
            } else {
                throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
            }
        }
    
        // 默认构造器 数组初始长度为 0 当添加第一个元素时 将数组容量扩充为 10
        public ArrayList() {
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
        }
    
        public ArrayList(Collection<? extends E> c) { /*...*/ }
    
        public void trimToSize() {
            modCount++;
            if (size < elementData.length) {
                elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size);
            }
        }
    
        // 确保数组容量不小于 minCapacity
        // 用于在添加元素前使用 减少添加过程中数组扩容消耗的时间
        public void ensureCapacity(int minCapacity) {
            if (minCapacity > elementData.length
                && !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA && minCapacity <= DEFAULT_CAPACITY)) {
            	// 当前为默认构造器构造的空列表 且 minCapacity <= 10 不会扩容
            	// 因为该情况下 加入第一个元素时 容量就会扩大到 10
                modCount++;
                grow(minCapacity);
            }
        }
    
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
        // 扩容
    
        private Object[] grow(int minCapacity) {
            return elementData = Arrays.copyOf(elementData, newCapacity(minCapacity));
        }
    
        private Object[] grow() {
            return grow(size + 1);
        }
    
        // minCapacity >= 1.5 * size 扩容到 minCapacity
        // minCapacity <  1.5 * size 扩容 1.5 倍
        // 最少扩容 50%
        private int newCapacity(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity <= 0) {
                if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)	// 当前为默认构造器构造的空列表
                    return Math.max(DEFAULT_CAPACITY, minCapacity);		// 至少扩容到 10
                if (minCapacity < 0) // overflow
                    throw new OutOfMemoryError();
                return minCapacity;
            }
            return (newCapacity - MAX_ARRAY_SIZE <= 0) ? newCapacity : hugeCapacity(minCapacity);
        }
    
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
        }
    
        // Positional Access Operations
    
        @SuppressWarnings("unchecked")
        E elementData(int index) {
            return (E) elementData[index];
        }
    
        @SuppressWarnings("unchecked")
        static <E> E elementAt(Object[] es, int index) {
            return (E) es[index];
        }
    
        public E get(int index) {
            Objects.checkIndex(index, size);
            return elementData(index);
        }
    
        public E set(int index, E element) {
            Objects.checkIndex(index, size);
            E oldValue = elementData(index);
            elementData[index] = element;
            return oldValue;
        }
    
        private void add(E e, Object[] elementData, int s) {
            if (s == elementData.length)
                elementData = grow(); // 等价于 grow(size+1) minCapacity = size+1
            elementData[s] = e;
            size = s + 1;
        }
    
        public boolean add(E e) {
            modCount++;
            add(e, elementData, size);
            return true;
        }
    
        public void add(int index, E element) {
            rangeCheckForAdd(index);
            modCount++;
            final int s;
            Object[] elementData;
            if ((s = size) == (elementData = this.elementData).length)
                elementData = grow();
            System.arraycopy(elementData, index, elementData, index + 1, s - index);
            elementData[index] = element;
            size = s + 1;
        }
    
        public E remove(int index) {
            Objects.checkIndex(index, size);
            final Object[] es = elementData;
    
            @SuppressWarnings("unchecked") E oldValue = (E) es[index];
            fastRemove(es, index);
    
            return oldValue;
        }
    
        /**
         * Private remove method that skips bounds checking and does not
         * return the value removed.
         */
        private void fastRemove(Object[] es, int i) {
            modCount++;
            final int newSize;
            if ((newSize = size - 1) > i)
                System.arraycopy(es, i + 1, es, i, newSize - i);
            es[size = newSize] = null;
        }
    
        // 数组长度不变
        public void clear() {
            modCount++;
            final Object[] es = elementData;
            for (int to = size, i = size = 0; i < to; i++)
                es[i] = null;
        }
    
        /**
         * An optimized version of AbstractList.Itr
         */
        private class Itr implements Iterator<E> { /*...*/ }
    
        /**
         * An optimized version of AbstractList.ListItr
         */
        private class ListItr extends Itr implements ListIterator<E> { /*...*/ }
    
        private static class SubList<E> extends AbstractList<E> implements RandomAccess { /*...*/ }
    
        @Override
        public void forEach(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            final int expectedModCount = modCount;
            final Object[] es = elementData;
            final int size = this.size;
            for (int i = 0; modCount == expectedModCount && i < size; i++)
                action.accept(elementAt(es, i));
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    
        @Override
        public Spliterator<E> spliterator() {
            return new ArrayListSpliterator(0, -1, 0);
        }
    
        /** Index-based split-by-two, lazily initialized Spliterator */
        final class ArrayListSpliterator implements Spliterator<E> { /*...*/ }
    }
    
    • ArrayList 扩容机制:数组复制 Arrays.copyOf(T[] original, int newLength) 方法
      添加元素时当前容量等于数组长度:

      • minCapacity = size + 1 调用 grow(minCapacity) 确保扩容后容量至少大 1

        • minCapacity < 1.5 * size 扩容 1.5 倍

        • minCapacity >= 1.5 * size

          • 默认构造器构造的空列表 扩容到 max(minCapacity, 10)
          • 其他情况 扩容到 minCapacity

      即一个默认构造器构造的空列表,第一次添加元素时,数组长度由 0 变为 10,之后按最少 1.5 倍扩容。
      而一个指定了初始容量的列表,每次添加元素时,都按照最少 1.5 倍扩容。

    • ArrayList 内部类 Itr 和 ListItr 基于数组的操作实现。

    Vector

    
    public class Vector<E>
        extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
    
        protected Object[] elementData;
    
        /**
         * The number of valid components in this {@code Vector} object.
         * Components {@code elementData[0]} through
         * {@code elementData[elementCount-1]} are the actual items.
         *
         * @serial
         */
        protected int elementCount;
    
        /**
         * The amount by which the capacity of the vector is automatically
         * incremented when its size becomes greater than its capacity.  If
         * the capacity increment is less than or equal to zero, the capacity
         * of the vector is doubled each time it needs to grow.
         *
         * @serial
         */
        protected int capacityIncrement;
    
        public Vector(int initialCapacity, int capacityIncrement) {
            super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            this.elementData = new Object[initialCapacity];
            this.capacityIncrement = capacityIncrement;
        }
    
        public Vector(int initialCapacity) {
            this(initialCapacity, 0);
        }
    
        public Vector() {
            this(10);
        }
    
    
        private void grow(int minCapacity) {
            // overflow-conscious code
            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);
        }
    }
    
    • Vector 和 ArrayList 很相像,是线程安全版的 ArrayList,方法是 synchronized 修饰的。

    • Vector 不指定容量增量的情况下,扩容是将容量翻倍,默认初始容量同样为 10。

    Stack

    public class Stack<E> extends Vector<E> {
    
        public Stack() {
        }
    
        public E push(E item) {
            addElement(item);
    
            return item;
        }
    
        public synchronized E pop() {
            E       obj;
            int     len = size();
    
            obj = peek();
            removeElementAt(len - 1);
    
            return obj;
        }
    
        public synchronized E peek() {
            int     len = size();
    
            if (len == 0)
                throw new EmptyStackException();
            return elementAt(len - 1);
        }
    
        public boolean empty() {
            return size() == 0;
        }
    
        public synchronized int search(Object o) {
            int i = lastIndexOf(o);
    
            if (i >= 0) {
                return size() - i;
            }
            return -1;
        }
    
        private static final long serialVersionUID = 1224463164541339165L;
    }
    
    • Stack 继承自 Vector,同样是线程安全的。

    AbstractSequentialList

    public abstract class AbstractSequentialList<E> extends AbstractList<E> {
    
        protected AbstractSequentialList() {
        }
    
        // 通过 ListIterator 实现 ArrayList 是直接取数组元素
        public E get(int index) {
            try {
                return listIterator(index).next();
            } catch (NoSuchElementException exc) {
                throw new IndexOutOfBoundsException("Index: "+index);
            }
        }
    
        public E set(int index, E element) {
            try {
                ListIterator<E> e = listIterator(index);
                E oldVal = e.next();
                e.set(element);
                return oldVal;
            } catch (NoSuchElementException exc) {
                throw new IndexOutOfBoundsException("Index: "+index);
            }
        }
    
        public void add(int index, E element) {
            try {
                listIterator(index).add(element);
            } catch (NoSuchElementException exc) {
                throw new IndexOutOfBoundsException("Index: "+index);
            }
        }
    
        public E remove(int index) {
            try {
                ListIterator<E> e = listIterator(index);
                E outCast = e.next();
                e.remove();
                return outCast;
            } catch (NoSuchElementException exc) {
                throw new IndexOutOfBoundsException("Index: "+index);
            }
        }
    
    
        // Bulk Operations
    
        public boolean addAll(int index, Collection<? extends E> c) { /*...*/ }
    
    
        // Iterators
    
        // 返回的是 listIterator
        public Iterator<E> iterator() {
            return listIterator();
        }
    
        public abstract ListIterator<E> listIterator(int index);
    }
    
    • AbstractSequentialList 实现了基本的 add,remove 等方法,都是基于 ListIterator 来实现的。

    LinkdedList

    public class LinkedList<E>
        extends AbstractSequentialList<E>
        implements List<E>, Deque<E>, Cloneable, java.io.Serializable
    {
        transient int size = 0;
    
        /**
         * Pointer to first node.
         * Invariant: (first == null && last == null) ||
         *            (first.prev == null && first.item != null)
         */
        transient Node<E> first;
    
        /**
         * Pointer to last node.
         * Invariant: (first == null && last == null) ||
         *            (last.next == null && last.item != null)
         */
        transient Node<E> last;
    
        /**
         * Constructs an empty list.
         */
        public LinkedList() {
        }
    
        public LinkedList(Collection<? extends E> c) {
            this();
            addAll(c);
        }
    
        /**
         * Links e as first element.
         */
        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++;
        }
    
        /**
         * Links e as last element.
         */
        void linkLast(E e) { /*...*/ }
    
        /**
         * Inserts element e before non-null Node succ.
         */
        void linkBefore(E e, Node<E> succ) {
            // assert succ != null;
            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++;
        }
    
        /**
         * Unlinks non-null first node f.
         */
        private E unlinkFirst(Node<E> f) {
            // assert f == first && f != null;
            final E element = f.item;
            final Node<E> next = f.next;
            f.item = null;
            f.next = null; // help GC
            first = next;
            if (next == null)
                last = null;
            else
                next.prev = null;
            size--;
            modCount++;
            return element;
        }
    
        /**
         * Unlinks non-null last node l.
         */
        private E unlinkLast(Node<E> l) { /*...*/ }
    
        /**
         * Unlinks non-null node x.
         */
        E unlink(Node<E> x) {
            // assert x != null;
            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;
        }
    
        public E getFirst() {
            final Node<E> f = first;
            if (f == null)
                throw new NoSuchElementException();
            return f.item;
        }
    
        public E getLast() { /*...*/ }
    
        public E removeFirst() { /*...*/ }
    
        public E removeLast() { /*...*/ }
    
        public void addFirst(E e) { /*...*/ }
    
        public void addLast(E e) { /*...*/ }
    
        public boolean contains(Object o) {
            return indexOf(o) != -1;
        }
    
        public int size() { /*...*/ }
    
        // 尾插
        public boolean add(E e) {
            linkLast(e);
            return true;
        }
    
        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 boolean addAll(Collection<? extends E> c) { /*...*/ }
    
        public boolean addAll(int index, Collection<? extends E> c) { /*...*/ }
     
        public void clear() {
            // Clearing all of the links between nodes is "unnecessary", but:
            // - helps a generational GC if the discarded nodes inhabit
            //   more than one generation
            // - is sure to free memory even if there is a reachable Iterator
            for (Node<E> x = first; x != null; ) {
                Node<E> next = x.next;
                x.item = null;
                x.next = null;
                x.prev = null;
                x = next;
            }
            first = last = null;
            size = 0;
            modCount++;
        }
    
    
        // Positional Access Operations
    
        public E get(int index) {
            checkElementIndex(index);
            return node(index).item;
        }
    
        public E set(int index, E element) { /*...*/ }
    
        public void add(int index, E element) {
            checkPositionIndex(index);
    
            if (index == size)
                linkLast(element);
            else
                linkBefore(element, node(index));
        }
    
        public E remove(int index) {
            checkElementIndex(index);
            return unlink(node(index));
        }
    
        /**
         * Tells if the argument is the index of an existing element.
         */
        private boolean isElementIndex(int index) {
            return index >= 0 && index < size;
        }
    
        /**
         * Tells if the argument is the index of a valid position for an
         * iterator or an add operation.
         */
        private boolean isPositionIndex(int index) {
            return index >= 0 && index <= size;
        }
    
        /**
         * Returns the (non-null) Node at the specified element index.
         */
        Node<E> node(int index) {
            // assert isElementIndex(index);
            // 根据 index 判断结点在链表的前半段还是后半段
            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;
            }
        }
    
        // Search Operations
    
        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;
        }
    
        public int lastIndexOf(Object o) { /*...*/ }
    
        // Queue operations.
    
        public E peek() {
            final Node<E> f = first;
            return (f == null) ? null : f.item;
        }
    
        public E element() {
            return getFirst();
        }
    
        public E poll() {
            final Node<E> f = first;
            return (f == null) ? null : unlinkFirst(f);
        }
    
        public E remove() {
            return removeFirst();
        }
    
        public boolean offer(E e) {
            return add(e);
        }
    
        // Deque operations
        public boolean offerFirst(E e) { /*...*/ }
    
        public boolean offerLast(E e) { /*...*/ }
    
        public E peekFirst() { /*...*/ }
    
        public E peekLast() { /*...*/ }
    
        public E pollFirst() { /*...*/ }
    
        public E pollLast() { /*...*/ }
    
        public void push(E e) {
            addFirst(e);
        }
    
        public E pop() {
            return removeFirst();
        }
    
        public boolean removeFirstOccurrence(Object o) {
            return remove(o);
        }
    
        public boolean removeLastOccurrence(Object o) { /*...*/ }
    
        public ListIterator<E> listIterator(int index) {
            checkPositionIndex(index);
            return new ListItr(index);
        }
    
        private class ListItr implements ListIterator<E> {
            private Node<E> lastReturned;
            private Node<E> next;
            private int nextIndex;
            private int expectedModCount = modCount;
    
            ListItr(int index) {
                // assert isPositionIndex(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++;
            }
    
            public void forEachRemaining(Consumer<? super E> action) {
                Objects.requireNonNull(action);
                while (modCount == expectedModCount && nextIndex < size) {
                    action.accept(next.item);
                    lastReturned = next;
                    next = next.next;
                    nextIndex++;
                }
                checkForComodification();
            }
    
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
    
        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();
        }
    
        /**
         * Adapter to provide descending iterators via ListItr.previous
         */
        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();
            }
        }
    }
    
    • LinkedList 实现了 List,Deque 接口,可以作为列表,队列,双向队列来使用。

    • LinkedList 内部类 Node 中三个属性:item,prev,next。

    • LinkedList 内部类 ListItr,和 DescendingIterator。DescendingIterator 使用适配器模式,将 ListItr 转化为反向的迭代器。

  • 相关阅读:
    php入门到精通(复习笔记)
    MySQL的基础(优化)3
    php之Apache压力测试
    DOS下常用命令
    php连接MySQL分析
    php-memcached详解
    php 四种基本排序算法
    MySQL的基础(优化)2
    SQL入门之集合操作
    SQL入门之多表查询
  • 原文地址:https://www.cnblogs.com/JL916/p/12729408.html
Copyright © 2011-2022 走看看