资讯专栏INFORMATION COLUMN

ArrayList源码解读(二)

HtmlCssJs / 976人阅读

摘要:删除错有缓冲区里的数据实际存储数据置,从到实际存储的位置循环置添加集合到当前集合转化为数组添加数据长度长度为直接返回旧数据长度新数据长度大于缓冲区大小,就扩容扩大为可以容纳旧数据新数据大小新数据从位开始复制到缓冲区的位处,复制长度为新数据

clear()删除错有缓冲区里的数据

public void clear() {
        modCount++;
        final Object[] es = elementData;
        for (int to = size, i = size = 0; i < to; i++)//实际存储数据置0,从0到实际存储的位置循环置null
            es[i] = null;
    }

addAll(Collection c)添加集合到当前集合

 public boolean addAll(Collection c) {
        Object[] a = c.toArray();//转化为数组
        modCount++;
        int numNew = a.length;//添加数据长度
        if (numNew == 0)
            return false;//长度为0直接返回false
        Object[] elementData;
        final int s;
        if (numNew > (elementData = this.elementData).length - (s = size))//旧数据长度+新数据长度大于缓冲区大小,就扩容
            elementData = grow(s + numNew);//扩大为可以容纳旧数据+新数据大小
        System.arraycopy(a, 0, elementData, s, numNew);//新数据从0位开始复制到缓冲区的s位处,复制长度为新数据长度
        size = s + numNew;
        return true;
    }

addAll(int index, Collection c)添加集合到当前集合的固定位置

 public boolean addAll(int index, Collection c) {
        rangeCheckForAdd(index);//确认下标

        Object[] a = c.toArray();//转数组
        modCount++;
        int numNew = a.length;
        if (numNew == 0)
            return false;//长度为0直接返回
        Object[] elementData;
        final int s;
        if (numNew > (elementData = this.elementData).length - (s = size))//旧数据长度+新数据长度大于缓冲区大小,就扩容
            elementData = grow(s + numNew);

        int numMoved = s - index;//存储长度减去index得出就是要移动数据的长度
        if (numMoved > 0)
            System.arraycopy(elementData, index,elementData, index + numNew,numMoved);//把缓冲区从index移动到index + numNew,移动长度为numMoved 
        System.arraycopy(a, 0, elementData, index, numNew);//把集合从0位移动到缓冲区index位,共移动集合的长度个数据
        size = s + numNew;//实际存储数更改为size+集合长度
        return true;//返回true
    }

removeRange(int fromIndex, int toIndex)删除介于(包含)fromIndex和toIndex(不包含)的所有元素

  protected void removeRange(int fromIndex, int toIndex) {
        if (fromIndex > toIndex) {
            throw new IndexOutOfBoundsException(
                    outOfBoundsMsg(fromIndex, toIndex));
        }
        modCount++;
        shiftTailOverGap(elementData, fromIndex, toIndex);
    }

shiftTailOverGap(Object[] es, int lo, int hi)删除lo(包含)到hi(不包含)期间的元素

 private void shiftTailOverGap(Object[] es, int lo, int hi) {
        System.arraycopy(es, hi, es, lo, size - hi);//从hi位以后的数据复制到lo位,共复制size-hi个数据
        for (int to = size, i = (size -= hi - lo); i < to; i++)
            es[i] = null;//置0
    }

rangeCheckForAdd(int 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;
    }
    
    
private static String outOfBoundsMsg(int fromIndex, int toIndex) {
        return "From Index: " + fromIndex + " > To Index: " + toIndex;
    }

removeAll(Collection c) 删除缓冲区中,集合包含的数据

 public boolean removeAll(Collection c) {
        return batchRemove(c, false, 0, size);
    }

retainAll(Collection c)保留缓冲区中,集合包含的数据

public boolean retainAll(Collection c) {
        return batchRemove(c, true, 0, size);
    }

batchRemove(Collection c, boolean complement,final int from, final int end)false是删除传入集合包含元素,true是保留传入集合包含元素

boolean batchRemove(Collection c, boolean complement,
                        final int from, final int end) {
        Objects.requireNonNull(c);
        final Object[] es = elementData;
        int r;
        // Optimize for initial run of survivors
        for (r = from;; r++) {
            if (r == end)//操作长度为0直接返回false
                return false;
            if (c.contains(es[r]) != complement)//为true的时候,查找到第一个不保留位r。为false时候查找到第一个要删除的位
                break;
        }
        int w = r++;
        try {
            for (Object e; r < end; r++)
                if (c.contains(e = es[r]) == complement)//为true时把在集合的元素往前移,为false时,不在集合的元素往前移动
                    es[w++] = e;
        } catch (Throwable ex) {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            System.arraycopy(es, r, es, w, end - r);
            w += end - r;
            throw ex;
        } finally {
            modCount += end - w;
            shiftTailOverGap(es, w, end);//删除尾部元素
        }
        return true;
    }

writeObject(java.io.ObjectOutputStream s)输出对象

private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject();

        // Write out size as capacity for behavioral compatibility with clone()
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (int i=0; i

readObject(java.io.ObjectInputStream s)读取对象

private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {

        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // Read in capacity
        s.readInt(); // ignored

        if (size > 0) {//数据量大于0
            // like clone(), allocate array based upon size not capacity
            SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
            Object[] elements = new Object[size];

            // Read in all elements in the proper order.
            for (int i = 0; i < size; i++) {
                elements[i] = s.readObject();
            }

            elementData = elements;
        } else if (size == 0) {//数据量等于0
            elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new java.io.InvalidObjectException("Invalid size: " + size);
        }
    }

listIterator()返回迭代器

public ListIterator listIterator() {
        return new ListItr(0);
    }

listIterator(int index)返回迭代器

public ListIterator listIterator(int index) {
        rangeCheckForAdd(index);//
        return new ListItr(index);
    }
Itr内部类
private class Itr implements Iterator {
        int cursor;       // 要返回的下一个元素的索引
        int lastRet = -1; // 返回最后一个元素的索引; 如果没有这样的话-1
        int expectedModCount = modCount;

        // prevent creating a synthetic constructor
        Itr() {}

        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];//最后一个元素的索引改成i
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);//移除最后返回的元素
                cursor = lastRet;//光标回退
                lastRet = -1;//最后返回的元素被删除,索引变为-1
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        @Override
        public void forEachRemaining(Consumer action) {//循环剩余
            Objects.requireNonNull(action);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i < size) {//
                final Object[] es = elementData;
                if (i >= es.length)
                    throw new ConcurrentModificationException();//线程异常
                for (; i < size && modCount == expectedModCount; i++)
                    action.accept(elementAt(es, i));//把缓冲区es中i处元素放进accept方法里
                // update once at end to reduce heap write traffic
                cursor = i;
                lastRet = i - 1;
                checkForComodification();
            }
        }

        final void checkForComodification() {//线程安全
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

subList(int fromIndex, int toIndex)返回集合的部分(类型变成了SubList)

public List subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList<>(this, fromIndex, toIndex);
    }
ListItr 内部类
 private class ListItr extends Itr implements ListIterator {
        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)//最后操作位必须大于0,即进行删除操作后得滑动索引,不然会报IllegalStateException
                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();
            }
        }
    }

subList(int fromIndex, int toIndex)

public List subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList<>(this, fromIndex, toIndex);
    }
静态内部类SubList
private static class SubList extends AbstractList implements RandomAccess {
        private final ArrayList root;
        private final SubList parent;
        private final int offset;
        private int size;

        /**
         * Constructs a sublist of an arbitrary ArrayList.
         */
        public SubList(ArrayList root, int fromIndex, int toIndex) {
            this.root = root;
            this.parent = null;
            this.offset = fromIndex;
            this.size = toIndex - fromIndex;
            this.modCount = root.modCount;
        }

        /**
         * Constructs a sublist of another SubList.
         */
        private SubList(SubList parent, int fromIndex, int toIndex) {
            this.root = parent.root;
            this.parent = parent;
            this.offset = parent.offset + fromIndex;
            this.size = toIndex - fromIndex;
            this.modCount = root.modCount;
        }

        public E set(int index, E element) {
            Objects.checkIndex(index, size);
            checkForComodification();
            E oldValue = root.elementData(offset + index);
            root.elementData[offset + index] = element;
            return oldValue;
        }

        public E get(int index) {
            Objects.checkIndex(index, size);
            checkForComodification();
            return root.elementData(offset + index);
        }

        public int size() {
            checkForComodification();
            return size;
        }

        public void add(int index, E element) {
            rangeCheckForAdd(index);
            checkForComodification();
            root.add(offset + index, element);
            updateSizeAndModCount(1);
        }

        public E remove(int index) {
            Objects.checkIndex(index, size);
            checkForComodification();
            E result = root.remove(offset + index);
            updateSizeAndModCount(-1);
            return result;
        }

        protected void removeRange(int fromIndex, int toIndex) {
            checkForComodification();
            root.removeRange(offset + fromIndex, offset + toIndex);
            updateSizeAndModCount(fromIndex - toIndex);
        }

        public boolean addAll(Collection c) {
            return addAll(this.size, c);
        }

        public boolean addAll(int index, Collection c) {
            rangeCheckForAdd(index);
            int cSize = c.size();
            if (cSize==0)
                return false;
            checkForComodification();
            root.addAll(offset + index, c);
            updateSizeAndModCount(cSize);
            return true;
        }

        public void replaceAll(UnaryOperator operator) {
            root.replaceAllRange(operator, offset, offset + 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) {
            checkForComodification();
            int oldSize = root.size;
            boolean modified =
                root.batchRemove(c, complement, offset, offset + size);
            if (modified)
                updateSizeAndModCount(root.size - oldSize);
            return modified;
        }

        public boolean removeIf(Predicate filter) {
            checkForComodification();
            int oldSize = root.size;
            boolean modified = root.removeIf(filter, offset, offset + size);
            if (modified)
                updateSizeAndModCount(root.size - oldSize);
            return modified;
        }

        public Object[] toArray() {
            checkForComodification();
            return Arrays.copyOfRange(root.elementData, offset, offset + size);
        }

        @SuppressWarnings("unchecked")
        public  T[] toArray(T[] a) {
            checkForComodification();
            if (a.length < size)
                return (T[]) Arrays.copyOfRange(
                        root.elementData, offset, offset + size, a.getClass());
            System.arraycopy(root.elementData, offset, a, 0, size);
            if (a.length > size)
                a[size] = null;
            return a;
        }

        public boolean equals(Object o) {
            if (o == this) {
                return true;
            }

            if (!(o instanceof List)) {
                return false;
            }

            boolean equal = root.equalsRange((List)o, offset, offset + size);
            checkForComodification();
            return equal;
        }

        public int hashCode() {
            int hash = root.hashCodeRange(offset, offset + size);
            checkForComodification();
            return hash;
        }

        public int indexOf(Object o) {
            int index = root.indexOfRange(o, offset, offset + size);
            checkForComodification();
            return index >= 0 ? index - offset : -1;
        }

        public int lastIndexOf(Object o) {
            int index = root.lastIndexOfRange(o, offset, offset + size);
            checkForComodification();
            return index >= 0 ? index - offset : -1;
        }

        public boolean contains(Object o) {
            return indexOf(o) >= 0;
        }

        public Iterator iterator() {
            return listIterator();
        }

        public ListIterator listIterator(int index) {
            checkForComodification();
            rangeCheckForAdd(index);

            return new ListIterator() {
                int cursor = index;
                int lastRet = -1;
                int expectedModCount = root.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 = root.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 = root.elementData;
                    if (offset + i >= elementData.length)
                        throw new ConcurrentModificationException();
                    cursor = i;
                    return (E) elementData[offset + (lastRet = i)];
                }

                public void forEachRemaining(Consumer action) {
                    Objects.requireNonNull(action);
                    final int size = SubList.this.size;
                    int i = cursor;
                    if (i < size) {
                        final Object[] es = root.elementData;
                        if (offset + i >= es.length)
                            throw new ConcurrentModificationException();
                        for (; i < size && modCount == expectedModCount; i++)
                            action.accept(elementAt(es, offset + i));
                        // update once at end to reduce heap write traffic
                        cursor = i;
                        lastRet = i - 1;
                        checkForComodification();
                    }
                }

                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 = root.modCount;
                    } catch (IndexOutOfBoundsException ex) {
                        throw new ConcurrentModificationException();
                    }
                }

                public void set(E e) {
                    if (lastRet < 0)
                        throw new IllegalStateException();
                    checkForComodification();

                    try {
                        root.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 = root.modCount;
                    } catch (IndexOutOfBoundsException ex) {
                        throw new ConcurrentModificationException();
                    }
                }

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

        public List subList(int fromIndex, int toIndex) {
            subListRangeCheck(fromIndex, toIndex, size);
            return new SubList<>(this, fromIndex, toIndex);
        }

        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 (root.modCount != modCount)
                throw new ConcurrentModificationException();
        }

        private void updateSizeAndModCount(int sizeChange) {
            SubList slist = this;
            do {
                slist.size += sizeChange;
                slist.modCount = root.modCount;
                slist = slist.parent;
            } while (slist != null);
        }

        public Spliterator spliterator() {
            checkForComodification();

            // ArrayListSpliterator not used here due to late-binding
            return new Spliterator() {
                private int index = offset; // current index, modified on advance/split
                private int fence = -1; // -1 until used; then one past last index
                private int expectedModCount; // initialized when fence set

                private int getFence() { // initialize fence to size on first use
                    int hi; // (a specialized variant appears in method forEach)
                    if ((hi = fence) < 0) {
                        expectedModCount = modCount;
                        hi = fence = offset + size;
                    }
                    return hi;
                }

                public ArrayList.ArrayListSpliterator trySplit() {
                    int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
                    // ArrayListSpliterator can be used here as the source is already bound
                    return (lo >= mid) ? null : // divide range in half unless too small
                        root.new ArrayListSpliterator(lo, index = mid, expectedModCount);
                }

                public boolean tryAdvance(Consumer action) {
                    Objects.requireNonNull(action);
                    int hi = getFence(), i = index;
                    if (i < hi) {
                        index = i + 1;
                        @SuppressWarnings("unchecked") E e = (E)root.elementData[i];
                        action.accept(e);
                        if (root.modCount != expectedModCount)
                            throw new ConcurrentModificationException();
                        return true;
                    }
                    return false;
                }

                public void forEachRemaining(Consumer action) {
                    Objects.requireNonNull(action);
                    int i, hi, mc; // hoist accesses and checks from loop
                    ArrayList lst = root;
                    Object[] a;
                    if ((a = lst.elementData) != null) {
                        if ((hi = fence) < 0) {
                            mc = modCount;
                            hi = offset + size;
                        }
                        else
                            mc = expectedModCount;
                        if ((i = index) >= 0 && (index = hi) <= a.length) {
                            for (; i < hi; ++i) {
                                @SuppressWarnings("unchecked") E e = (E) a[i];
                                action.accept(e);
                            }
                            if (lst.modCount == mc)
                                return;
                        }
                    }
                    throw new ConcurrentModificationException();
                }

                public long estimateSize() {
                    return getFence() - index;
                }

                public int characteristics() {
                    return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
                }
            };
        }
    }

forEach(Consumer action)迭代元素

 @Override
    public void forEach(Consumer 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++)//循环0到实际长度
            action.accept(elementAt(es, i));//对应下标值放入accept方法
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();//线程安全
    }

spliterator() 返回分裂器

 @Override
    public Spliterator spliterator() {
        return new ArrayListSpliterator(0, -1, 0);
    }
内部类ArrayListSpliterator (基于索引的二分裂,懒惰初始化的Spliterator)
final class ArrayListSpliterator implements Spliterator {

        /*
         * If ArrayLists were immutable, or structurally immutable (no
         * adds, removes, etc), we could implement their spliterators
         * with Arrays.spliterator. Instead we detect as much
         * interference during traversal as practical without
         * sacrificing much performance. We rely primarily on
         * modCounts. These are not guaranteed to detect concurrency
         * violations, and are sometimes overly conservative about
         * within-thread interference, but detect enough problems to
         * be worthwhile in practice. To carry this out, we (1) lazily
         * initialize fence and expectedModCount until the latest
         * point that we need to commit to the state we are checking
         * against; thus improving precision.  (This doesn"t apply to
         * SubLists, that create spliterators with current non-lazy
         * values).  (2) We perform only a single
         * ConcurrentModificationException check at the end of forEach
         * (the most performance-sensitive method). When using forEach
         * (as opposed to iterators), we can normally only detect
         * interference after actions, not before. Further
         * CME-triggering checks apply to all other possible
         * violations of assumptions for example null or too-small
         * elementData array given its size(), that could only have
         * occurred due to interference.  This allows the inner loop
         * of forEach to run without any further checks, and
         * simplifies lambda-resolution. While this does entail a
         * number of checks, note that in the common case of
         * list.stream().forEach(a), no checks or other computation
         * occur anywhere other than inside forEach itself.  The other
         * less-often-used methods cannot take advantage of most of
         * these streamlinings.
         */

        private int index; // 当前指数,在提前/拆分时修改
        private int fence; // -1直到使用; 然后是最后一个索引
        private int expectedModCount; // 栅栏设置时初始化

        /** 创建覆盖给定范围的新分裂器. */
        ArrayListSpliterator(int origin, int fence, int expectedModCount) {
            this.index = origin;
            this.fence = fence;
            this.expectedModCount = expectedModCount;
        }

        private int getFence() { // initialize fence to size on first use
            int hi; // (a specialized variant appears in method forEach)
            if ((hi = fence) < 0) {
                expectedModCount = modCount;
                hi = fence = size;
            }
            return hi;
        }

        public ArrayListSpliterator trySplit() {//拆分
            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
            return (lo >= mid) ? null : // divide range in half unless too small
                new ArrayListSpliterator(lo, index = mid, expectedModCount);
        }

        public boolean tryAdvance(Consumer action) {//迭代,若有下一位返回true
            if (action == null)
                throw new NullPointerException();
            int hi = getFence(), i = index;
            if (i < hi) {
                index = i + 1;
                @SuppressWarnings("unchecked") E e = (E)elementData[i];
                action.accept(e);
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                return true;
            }
            return false;
        }

        public void forEachRemaining(Consumer action) {
            int i, hi, mc; // hoist accesses and checks from loop
            Object[] a;
            if (action == null)
                throw new NullPointerException();
            if ((a = elementData) != null) {
                if ((hi = fence) < 0) {
                    mc = modCount;
                    hi = size;
                }
                else
                    mc = expectedModCount;
                if ((i = index) >= 0 && (index = hi) <= a.length) {
                    for (; i < hi; ++i) {
                        @SuppressWarnings("unchecked") E e = (E) a[i];
                        action.accept(e);
                    }
                    if (modCount == mc)
                        return;
                }
            }
            throw new ConcurrentModificationException();
        }

        public long estimateSize() {
            return getFence() - index;
        }

        public int characteristics() {
            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
        }
    }

removeIf(Predicate filter) 删除表达式返回true的元素

 @Override
    public boolean removeIf(Predicate filter) {
        return removeIf(filter, 0, size);
    }

removeIf(Predicate filter, int i, final int end)删除范围呃逆,表达式返回true的元素

boolean removeIf(Predicate filter, int i, final int end) {
        Objects.requireNonNull(filter);
        int expectedModCount = modCount;
        final Object[] es = elementData;//缓冲区
        // Optimize for initial run of survivors
        for (; i < end && !filter.test(elementAt(es, i)); i++)
            ;
        // Tolerate predicates that reentrantly access the collection for
        // read (but writers still get CME), so traverse once to find
        // elements to delete, a second pass to physically expunge.
        if (i < end) {
            final int beg = i;
            final long[] deathRow = nBits(end - beg);
            deathRow[0] = 1L;   // set bit 0
            for (i = beg + 1; i < end; i++)
                if (filter.test(elementAt(es, i)))
                    setBit(deathRow, i - beg);
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            modCount++;
            int w = beg;
            for (i = beg; i < end; i++)
                if (isClear(deathRow, i - beg))
                    es[w++] = es[i];
            shiftTailOverGap(es, w, end);
            return true;
        } else {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            return false;
        }
    }

replaceAll(UnaryOperator operator)替换范围内元素

 @Override
    public void replaceAll(UnaryOperator operator) {
        replaceAllRange(operator, 0, size);
        modCount++;
    }

replaceAllRange(UnaryOperator operator, int i, int end)替换范围内元素,每个元素都替换成执行UnaryOperator后的结果

private void replaceAllRange(UnaryOperator operator, int i, int end) {
        Objects.requireNonNull(operator);
        final int expectedModCount = modCount;
        final Object[] es = elementData;
        for (; modCount == expectedModCount && i < end; i++)
            es[i] = operator.apply(elementAt(es, i));
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }

sort(Comparator c)排序集合

 public void sort(Comparator c) {
        final int expectedModCount = modCount;
        Arrays.sort((E[]) elementData, 0, size, c);//调用Arrays.sort
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
        modCount++;
    }

checkInvariants() 检查不变量

void checkInvariants() {
        // assert size >= 0;
        // assert size == elementData.length || elementData[size] == null;
    }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74903.html

相关文章

  • java源码

    摘要:集合源码解析回归基础,集合源码解析系列,持续更新和源码分析与是两个常用的操作字符串的类。这里我们从源码看下不同状态都是怎么处理的。 Java 集合深入理解:ArrayList 回归基础,Java 集合深入理解系列,持续更新~ JVM 源码分析之 System.currentTimeMillis 及 nanoTime 原理详解 JVM 源码分析之 System.currentTimeMi...

    Freeman 评论0 收藏0
  • ArrayList源码解读(一)

    摘要:源码解读属性默认的初始化空间空的数组用于空对象初始化存储数组,非私有简化了嵌套类访问实际存储的数据量集合被操作次数,次数对不上抛出构造方法设置初始空间大小的构造方法大于就构造对应长度的数组等于就直接赋值空的数组对象小于就抛出异常无参构造方法 ArrayList源码解读 属性 private static final int DEFAULT_CAPACITY = 10;/...

    Meils 评论0 收藏0
  • dubbo源码解析()Dubbo扩展机制SPI

    摘要:二注解该注解为了保证在内部调用具体实现的时候不是硬编码来指定引用哪个实现,也就是为了适配一个接口的多种实现,这样做符合模块接口设计的可插拔原则,也增加了整个框架的灵活性,该注解也实现了扩展点自动装配的特性。 Dubbo扩展机制SPI 前一篇文章《dubbo源码解析(一)Hello,Dubbo》是对dubbo整个项目大体的介绍,而从这篇文章开始,我将会从源码来解读dubbo再各个模块的实...

    DirtyMind 评论0 收藏0
  • React 源码深度解读):首次 DOM 元素渲染 - Part 2

    摘要:本文将要讲解的调用栈是下面这个样子的平台无关相关如果看源码,我们会留意到很多相关的代码,我们暂时先将其忽略,会在后续的文章中进行讲解。现在我们来看一下各实例间的关系目前为止的调用栈平台无关相关下一篇讲解三总结本文讲解了转化为的过程。 欢迎关注我的公众号睿Talk,获取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 R...

    wean 评论0 收藏0
  • swoft| 源码解读系列: 启动阶段, swoft 都干了些啥?

    摘要:源码解读系列二启动阶段都干了些啥阅读框架源码了解启动阶段的那些事儿小伙伴刚接触的时候会感觉压力有点大更直观的说法是难开发组是不赞成难这个说法的的代码都是实现的而又是世界上最好的语言的代码阅读起来是很轻松的之后开发组会用系列源码解读文章深 date: 2018-8-01 14:22:17title: swoft| 源码解读系列二: 启动阶段, swoft 都干了些啥?descriptio...

    hqman 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<