Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >集合源码阅读:ArrayList

集合源码阅读:ArrayList

作者头像
微风-- 轻许--
发布于 2022-04-13 08:32:52
发布于 2022-04-13 08:32:52
26600
代码可运行
举报
文章被收录于专栏:java 微风java 微风
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1.继承关系:

   public class ArrayList<E> extends AbstractList<E>
          implements List<E>, RandomAccess, Cloneable, java.io.Serializable
          
   ===================================================
   
    
2. 属性:

    // 默认容量
    private static final int DEFAULT_CAPACITY = 10;

    // 空数组,第一次存入元素时更新大小为 DEFAULT_CAPACITY
    private static final Object[] EMPTY_ELEMENTDATA = {};

    // 空数组,默认设定大小为 DEFAULT_CAPACITY
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    // 添加第一个元素时扩展到默认容量,transient:关闭序列化
    transient Object[] elementData;

    // 数组中元素个数
    private int size;
    
   ===================================================
   
    
3.方法:

   // 构造函数:initialCapacity 集合容量,该值为0时设定集合为 EMPTY_ELEMENTDATA,否则取其正值。
   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);
        }
    }
  
   // 无参构造:默认设定大小为 DEFAULT_CAPACITY
   public ArrayList() {
         this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
   }
   
   // 构造函数:拷贝已知集合,若参数为空集合则使用 EMPTY_ELEMENTDATA。
   public ArrayList(Collection<? extends E> c) {
           elementData = c.toArray();
           if ((size = elementData.length) != 0) {
               // c.toArray might (incorrectly) not return Object[] (see 6260652)
               if (elementData.getClass() != Object[].class)
                   elementData = Arrays.copyOf(elementData, size, Object[].class);
           } else {
               // replace with empty array.
               this.elementData = EMPTY_ELEMENTDATA;
           }
       }
     
   // 将容量调整为数组的当前大小,可以最小化存储空间。
   public void trimToSize() {
          modCount++;
          if (size < elementData.length) {
              elementData = (size == 0)
                ? EMPTY_ELEMENTDATA
                : Arrays.copyOf(elementData, size);
          }
      }
      
   // 增加此实例的容量,minCapacity 所需的最小容量
   public void ensureCapacity(int minCapacity) {
       int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
           // any size if not default element table
           ? 0
           // larger than default for default empty table. It's already
           // supposed to be at default size.
           : DEFAULT_CAPACITY;

       if (minCapacity > minExpand) {
           ensureExplicitCapacity(minCapacity);
       }
   }
   
   private void ensureCapacityInternal(int minCapacity) {
       if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
           minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
       }
       ensureExplicitCapacity(minCapacity);
   }

   private void ensureExplicitCapacity(int minCapacity) {
       modCount++;
       // overflow-conscious code
       if (minCapacity - elementData.length > 0)
           grow(minCapacity);
   }

   // 数组最大容量(分配过大容量可能会导致 OOM 异常,因为超过了虚拟机限制)
   private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

   // 增加容量到可以容纳 minCapacity 个元素。
   private void grow(int minCapacity) {
       // overflow-conscious code
       int oldCapacity = elementData.length;
       int newCapacity = oldCapacity + (oldCapacity >> 1);
       if (newCapacity - minCapacity < 0)
           newCapacity = minCapacity;
       if (newCapacity - MAX_ARRAY_SIZE > 0)
           newCapacity = hugeCapacity(minCapacity);
       // minCapacity is usually close to size, so this is a win:
       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;
   }
   
   // 返回集合元素个数
   public int size() {
       return size;
   }

   // 检查是否为空
   public boolean isEmpty() {
       return size == 0;
   }

   // 检查是否存在元素: o 
   public boolean contains(Object o) {
       return indexOf(o) >= 0;
   }
   
   // 返回指定元素第一次出现的索引,无则返回 -1 。
   public int indexOf(Object o) {
       if (o == null) {
           for (int i = 0; i < size; i++)
               if (elementData[i]==null)
                   return i;
       } else {
           for (int i = 0; i < size; i++)
               if (o.equals(elementData[i]))
                   return i;
       }
       return -1;
   }
   
   // 返回指定元素最后一次出现的索引,无则返回 -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;
   }
   
   // 浅clone,不会复制元素本身。
   public Object clone() {
       try {
           ArrayList<?> v = (ArrayList<?>) super.clone();
           v.elementData = Arrays.copyOf(elementData, size);
           v.modCount = 0;
           return v;
       } catch (CloneNotSupportedException e) {
           // this shouldn't happen, since we are Cloneable
           throw new InternalError(e);
       }
   }
   
   // 返回包含所有元素的数组,该数组是安全的。(此方法分配的是一个全新的数组,没有对它的引用存在,故调用者可对其自由修改。)
   public Object[] toArray() {
       return Arrays.copyOf(elementData, size);
   }

   // 返回包含参数数组中所有元素的数组。
   @SuppressWarnings("unchecked")
   public <T> T[] toArray(T[] a) {
       if (a.length < size)
           // 建一个 a 类型的新数组, 并填充当前集合的元素到其中。
           return (T[]) Arrays.copyOf(elementData, size, a.getClass());
       System.arraycopy(elementData, 0, a, 0, size);
       if (a.length > size)
           a[size] = null;
       return a;
   }

   // 返回对应索引位的元素   
   @SuppressWarnings("unchecked")
   E elementData(int index) {
       return (E) elementData[index];
   }
   
   // 返回对应索引位的元素,提供对外访问,调用上一方法。 
   public E get(int index) {
       rangeCheck(index);
       return elementData(index);
   }
   
   // 替换对应索引位的元素
   public E set(int index, E element) {
       rangeCheck(index);

       E oldValue = elementData(index);
       elementData[index] = element;
       return oldValue;
   }
   
   // 于末尾新增指定元素
   public boolean add(E e) {
       ensureCapacityInternal(size + 1);  // Increments modCount!!
       elementData[size++] = e;
       return true;
   }
   
   // 指定索引位插入式新增
   public void add(int index, E element) {
       rangeCheckForAdd(index);

       ensureCapacityInternal(size + 1);  // Increments modCount!!
       System.arraycopy(elementData, index, elementData, index + 1,
                        size - index);
       elementData[index] = element;
       size++;
   }
   
   // 移除对应索引位元素
   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; // clear to let GC do its work

       return oldValue;
   }
   
   // 删除第一个匹配指定元素的元素,若不存在匹配元素则不变。
   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;
   }
   
   // 快速删除:跳过边界检查,且无返回
   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; // clear to let GC do its work
   }
   
   // 清空集合
   public void clear() {
       modCount++;

       // clear to let GC do its work
       for (int i = 0; i < size; i++)
           elementData[i] = null;

       size = 0;
   }
   
   // 追加指定非空集合所有元素到本集合末尾
   public boolean addAll(Collection<? extends E> c) {
       Object[] a = c.toArray();
       int numNew = a.length;
       ensureCapacityInternal(size + numNew);  // Increments modCount
       System.arraycopy(a, 0, elementData, size, numNew);
       size += numNew;
       return numNew != 0;
   }
   
   // 从指定位置开始插入指定非空集合中的所有元素
   public boolean addAll(int index, Collection<? extends E> c) {
       rangeCheckForAdd(index);

       Object[] a = c.toArray();
       int numNew = a.length;
       ensureCapacityInternal(size + numNew);  // Increments modCount

       int numMoved = size - index;
       if (numMoved > 0)
           System.arraycopy(elementData, index, elementData, index + numNew,
                            numMoved);

       System.arraycopy(a, 0, elementData, index, numNew);
       size += numNew;
       return numNew != 0;
   }
   
   // 删除介于指定索引位之间的元素
   protected void removeRange(int fromIndex, int toIndex) {
       modCount++;
       int numMoved = size - toIndex;
       System.arraycopy(elementData, toIndex, elementData, fromIndex,
                        numMoved);

       // clear to let GC do its work
       int newSize = size - (toIndex-fromIndex);
       for (int i = newSize; i < size; i++) {
           elementData[i] = null;
       }
       size = newSize;
   }
   
   // 检查指定索引位是否大于集合总容量,此方法在访问数组元素前使用。
   private void rangeCheck(int index) {
       if (index >= size)
           throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
   }

   // add 和 addAll使用的 rangeCheck 版本
   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) {
       Objects.requireNonNull(c);
       return batchRemove(c, false);
   }
   
   // 仅保留指定集合中的元素,删除其余元素。
   public boolean retainAll(Collection<?> c) {
       Objects.requireNonNull(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 {
           // Preserve behavioral compatibility with AbstractCollection,
           // even if c.contains() throws.
           if (r != size) {
               System.arraycopy(elementData, r,
                                elementData, w,
                                size - r);
               w += size - r;
           }
           if (w != size) {
               // clear to let GC do its work
               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{
       // Write out element count, and any hidden stuff
       int expectedModCount = modCount;
       s.defaultWriteObject();

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

       // Write out all elements in the proper order.
       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;

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

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

       if (size > 0) {
           // be like clone(), allocate array based upon size not capacity
           ensureCapacityInternal(size);

           Object[] a = elementData;
           // Read in all elements in the proper order.
           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();
   }
   
   // AbstractList.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 != 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();
           }
       }
   
       @Override
       @SuppressWarnings("unchecked")
       public void forEachRemaining(Consumer<? super E> consumer) {
           Objects.requireNonNull(consumer);
           final int size = ArrayList.this.size;
           int i = cursor;
           if (i >= size) {
               return;
           }
           final Object[] elementData = ArrayList.this.elementData;
           if (i >= elementData.length) {
               throw new ConcurrentModificationException();
           }
           while (i != size && modCount == expectedModCount) {
               consumer.accept((E) elementData[i++]);
           }
           // update once at end of iteration to reduce heap write traffic
           cursor = i;
           lastRet = i - 1;
           checkForComodification();
       }

       final void checkForComodification() {
           if (modCount != expectedModCount)
               throw new ConcurrentModificationException();
       }
   }
   
   // AbstractList.ListItr 的优化版本
   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();
           }
       }
   }
   
   // 返回子集合,前闭后开。fromIndex = toIndex 时返回空集合。
   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)];
               }

               @SuppressWarnings("unchecked")
               public void forEachRemaining(Consumer<? super E> consumer) {
                   Objects.requireNonNull(consumer);
                   final int size = SubList.this.size;
                   int i = cursor;
                   if (i >= size) {
                       return;
                   }
                   final Object[] elementData = ArrayList.this.elementData;
                   if (offset + i >= elementData.length) {
                       throw new ConcurrentModificationException();
                   }
                   while (i != size && modCount == expectedModCount) {
                       consumer.accept((E) elementData[offset + (i++)]);
                   }
                   // update once at end of iteration to reduce heap write traffic
                   lastRet = cursor = i;
                   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 = 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 Spliterator<E> spliterator() {
           checkForComodification();
           return new ArrayListSpliterator<E>(ArrayList.this, offset,
                                              offset + this.size, this.modCount);
       }
   }
   
   @Override
   public void forEach(Consumer<? super E> action) {
       Objects.requireNonNull(action);
       final int expectedModCount = modCount;
       @SuppressWarnings("unchecked")
       final E[] elementData = (E[]) this.elementData;
       final int size = this.size;
       for (int i=0; modCount == expectedModCount && i < size; i++) {
           action.accept(elementData[i]);
       }
       if (modCount != expectedModCount) {
           throw new ConcurrentModificationException();
       }
   }
   
   // 创建一个拆分器,@since 1.8。
   @Override
   public Spliterator<E> spliterator() {
       return new ArrayListSpliterator<>(this, 0, -1, 0);
   }

   // 延迟初始化的拆分器。
   static final class ArrayListSpliterator<E> implements Spliterator<E> {

       // 如果集合结构是不变的,没有CRUD操作,则用 Arrays.spliterator 实现拆分. 
       private final ArrayList<E> list;
       private int index; // current index, modified on advance/split
       private int fence; // -1 until used; then one past last index
       private int expectedModCount; // initialized when fence set

       / Create new spliterator covering the given  range /
       ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
                            int expectedModCount) {
           this.list = list; // OK if null unless traversed
           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)
           ArrayList<E> lst;
           if ((hi = fence) < 0) {
               if ((lst = list) == null)
                   hi = fence = 0;
               else {
                   expectedModCount = lst.modCount;
                   hi = fence = lst.size;
               }
           }
           return hi;
       }

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

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

       public void forEachRemaining(Consumer<? super E> action) {
           int i, hi, mc; // hoist accesses and checks from loop
           ArrayList<E> lst; Object[] a;
           if (action == null)
               throw new NullPointerException();
           if ((lst = list) != null && (a = lst.elementData) != null) {
               if ((hi = fence) < 0) {
                   mc = lst.modCount;
                   hi = lst.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 (long) (getFence() - index);
       }

       public int characteristics() {
           return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
       }
   }
   
   // Predicate 函数式编程,参见个人博客 :https://blog.csdn.net/jiangyu1013/article/details/103500724
   @Override
   public boolean removeIf(Predicate<? super E> filter) {
       Objects.requireNonNull(filter);
       // figure out which elements are to be removed
       // any exception thrown from the filter predicate at this stage
       // will leave the collection unmodified
       int removeCount = 0;
       final BitSet removeSet = new BitSet(size);
       final int expectedModCount = modCount;
       final int size = this.size;
       for (int i=0; modCount == expectedModCount && i < size; i++) {
           @SuppressWarnings("unchecked")
           final E element = (E) elementData[i];
           if (filter.test(element)) {
               removeSet.set(i);
               removeCount++;
           }
       }
       if (modCount != expectedModCount) {
           throw new ConcurrentModificationException();
       }

       // shift surviving elements left over the spaces left by removed elements
       final boolean anyToRemove = removeCount > 0;
       if (anyToRemove) {
           final int newSize = size - removeCount;
           for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
               i = removeSet.nextClearBit(i);
               elementData[j] = elementData[i];
           }
           for (int k=newSize; k < size; k++) {
               elementData[k] = null;  // Let gc do its work
           }
           this.size = newSize;
           if (modCount != expectedModCount) {
               throw new ConcurrentModificationException();
           }
           modCount++;
       }

       return anyToRemove;
   }

   // Predicate 函数式编程,参见个人博客 :https://blog.csdn.net/jiangyu1013/article/details/103500724
   @Override
   @SuppressWarnings("unchecked")
   public void replaceAll(UnaryOperator<E> operator) {
       Objects.requireNonNull(operator);
       final int expectedModCount = modCount;
       final int size = this.size;
       for (int i=0; modCount == expectedModCount && i < size; i++) {
           elementData[i] = operator.apply((E) elementData[i]);
       }
       if (modCount != expectedModCount) {
           throw new ConcurrentModificationException();
       }
       modCount++;
   }
   
   @Override
   @SuppressWarnings("unchecked")
   public void sort(Comparator<? super E> c) {
       final int expectedModCount = modCount;
       Arrays.sort((E[]) elementData, 0, size, c);
       if (modCount != expectedModCount) {
           throw new ConcurrentModificationException();
       }
       modCount++;
   }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/03/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
python学习(二):列表嵌套
python里的列表和数组类似但不等同于数组,列表可以存放混合类型的数据,列表里不但能保存数据还能保存列表,接下来讲一下 列表里嵌套列表。
烤粽子
2021/07/07
1.5K0
Spack作业分析
给予4个文件【spack01.txt】【spack01.txt】【film_log1.csv】【move.csv】进行数据分析。
红目香薰
2022/11/30
1.1K0
Spack作业分析
hand first python选读(一)
列表很像数组,但功能超越数组。列表都是从0开始的,python中列表无需事先声明类型。
一粒小麦
2019/07/18
6550
hand first python选读(一)
python学习笔记3.3-高级函数技巧
本文介绍了Python中两个重要的函数技巧,一是递归函数,二是高阶函数。递归函数可以解决一些需要重复运算的问题,但需要注意避免栈溢出。高阶函数可以将函数的参数作为函数本身来使用,典型的高阶函数有map、filter等。通过使用高阶函数,可以简化代码,提高代码可读性。
锦小年
2018/01/02
6020
Python基础语法(三)——函数
抽象 抽象 抽象是数学中非常常见的概念。举个例子: 计算数列的和,比如:1 + 2 + 3 + ... + 100,写起来十分不方便,于是数学家发明了求和符号∑,可以把1 + 2 + 3 + ... + 100记作:
zeruns
2020/03/23
1.4K0
Python笔记(二):列表+列表数据处理+函数
#才疏学浅,难免有不恰当之处,请不吝指正,谢谢。 #适合初学者。     列表的数据自下而上堆放(形成一个堆栈),类似于其他编程语言的数组。例如: user = ["张三","李四","王五"] 王五 李四 张三 使用[]中括号偏移量访问列表数据: print(user[0])        输出: 张三 print(user[1])        输出:李四 print(user[2])        输出:王五 (一)列表常用的一些方法: append() :在
free赖权华
2018/04/27
9880
Python(2):创建函数模块
说明: 在使用python的时候我们除了使用内置的函数之外,可能还需要使用一些别人写的函数。或者我们写的代码也希望可以给其他人使用。要实现这样的功能,我们就需要按照下面的步骤来定义自己的模块: Step1:新建一个py文件 首先我们将前面一章所写的打印列表的函数保存为一个.py文件,假设我这里保存为 kider.py。 1 """ 2 这是一个打印列表的函数,如果列表中有嵌套的列表也会展开打印出来 3 """ 4 def print_list(movies): 5 if isinstance(mov
SecondWorld
2018/03/14
1.1K0
10 项网络安全国家标准获批发布
根据2022年4月15日国家市场监督管理总局、国家标准化管理委员会发布的中华人民共和国国家标准公告(2022年第6号),全国信息安全标准化技术委员会归口的10项国家标准正式发布。具体清单如下: 信息安全技术  智能家居通用安全规范 主要起草单位:中移(杭州)信息技术有限公司 、中国移动通信集团有限公司 、中国信息通信研究院 、公安部第三研究所 、国家计算机网络应急技术处理协调中心 、中国电子技术标准化研究院 、中国软件评测中心(工业和信息化部软件与集成电路促进中心) 、中国网络安全审查技术与认证中心 、北
云头条
2022/04/25
1.8K0
10 项网络安全国家标准获批发布
Python干货——函数(2)
👨‍🎓作者:Java学术趴 🏦仓库:Github、Gitee ✏️博客:CSDN、掘金、InfoQ、云+社区 💌公众号:Java学术趴 🚫特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系小编授权。 🙏版权声明:文章里的部分文字或者图片来自于互联网以及百度百科,如有侵权请尽快联系小编。 👋大家好!我是你们的老朋友Java学术趴。任何的语言都离不开函数,都包括内置函数和自定义函数,函数的作用就是对功能进行封装以便于无效调用。 9.4 函数的返回值 函数执行完之后会返回一个对象,如果函数中存在
Java学术趴
2022/06/04
8860
Python干货——函数(2)
Python 函数3000字使用总结
我们把一些经常或反复被使用的任务放在一起,创建一个函数,而不是为不同的输入反复编写相同的代码。
double
2020/07/21
1.5K0
Python 函数3000字使用总结
第三批国家“万人计划” 教学名师入选人员名单公布
教育部日前印发通知,公布了第三批国家“万人计划”教学名师入选名单,共195人。据悉,中央财政将为每一位入选者提供50万元特殊支持经费。 此次入选的国家“万人计划”教学名师涵盖各级各类学校,其中高校教师117人,中等以下学校(含普通中小学、中职、幼儿园、特殊教育学校等)教师78人。平均年龄53岁,地域上涵盖了全国31个省(区、市)及新疆生产建设兵团,学科门类包含工学、理学、文学等全部13个学科门类,以及中等以下学校的综合实践、科技教育、聋哑教育等相关专业,具有广泛的代表性。 国家“万人计划”教学名师是国家高
WZEARW
2018/04/08
2.5K0
基于Zero-shot实现LLM文本分类
我们的目的是期望模型能够帮助我们识别出这5段话中,每一句话描述的是一个什么类型的物体。
@小森
2024/06/09
5120
python实现明星专家系统
 其实一直对电影里面的对×××进行人脸匹配然后,刷出来×××信息很感兴趣,今天晚上一时兴起,就搞了一把小的。
py3study
2020/01/06
1.3K0
python递归-三元表达式-列表生成式-字典生成式-匿名函数-部分内置函数-04
应用场景: # 将列表中的数字依次打印出来(循环的层数是你必须要考虑的点)   -->  l = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, ]]]]]]]]]]]]]
suwanbin
2019/09/26
1K0
python递归-三元表达式-列表生成式-字典生成式-匿名函数-部分内置函数-04
Python进阶之递归函数的用法及其示例
本篇文章主要介绍了Python进阶之递归函数的用法及其示例,现在分享给大家,也给大家做个参考。一起来看看吧。
AI科技大本营
2020/03/13
5700
中文人物关系知识图谱(含码源):中文人物关系图谱构建、数据回标、基于远程监督人物关系抽取、知识问答等应用.
基于规则的方法,升级版的话,就是Bootstrapping了,可以通过用户自定义种子模板,不断迭代,最终扩充模式,但置信度这个问题不是很好解决
汀丶人工智能
2023/07/26
7120
中文人物关系知识图谱(含码源):中文人物关系图谱构建、数据回标、基于远程监督人物关系抽取、知识问答等应用.
0003-20180422-自动化第三章
内容回顾: 1. 计算机组成 2. 程序编译器 3. 变量 4. 条件 5. 循环 6. py2与py3区别 - 默认编码, - 除法, - input ,raw_input 7. 位,字节关系 8. 运算符: - and or - in not - py2 除法特殊代码 - += -= 9. 编码 汉字在utf-8里位3个字节,24位;汉字在GBK里是两个字节,16位 ascii --> unicode(4个字节,32位表示) ->(优化) utf-8/utf-16/utf-32 10. 字符串格式化 tpl = "asdfa&s,asdf%d" %("二哥", 666,) 问题: tpl = "我是%s",年龄%d,学习进度100%%" %('张勤学',99)
py3study
2020/01/19
4200
Python学习笔记(三)——函数
本文是廖雪峰的Python教程的笔记,主要是摘抄一些重点。所以我把他划分到转载里。侵删。
蛮三刀酱
2019/09/10
6690
Python基础10-函数的递归
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
DriverZeng
2022/09/26
2830
Python基础10-函数的递归
使用python的Django库开发一个简单的数据可视化网站(四)- 使用pyecharts进行数据可视化
上节课我们使用了Django连接了MySQL进行了数据的显示和数据的查询,这节课我们使用pyecharts进行数据可视化,由于之前已经讲了一期pyecharts的数据可视化,所以我们这节课会稍微简单一点。
你像时光唯美i
2022/08/26
1.7K0
相关推荐
python学习(二):列表嵌套
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验