List的实现类ArrayList各种方法源码解析

 

  1. list.add 方法实现

        //add方法 
        public boolean add(E e) {
            //size: elementData.size 
            ensureCapacityInternal(size + 1);  //判断数组的大小执行扩容以及copy
            elementData[size++] = e;//执行数组的添加以及size+1
            return true;
        }
        
        //ensureCapacityInternal 方法
        //minCapacity 最小适合的容量
        private void ensureCapacityInternal(int minCapacity) {
            //数组的初始化操作 判断elementData 和 初始定义的数组是否相等
            //若相等 执行初始化数组容量为10操作
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
            //判断当前数组的容量是否可以容纳当前数据的add操作
            ensureExplicitCapacity(minCapacity);
        }
        
        //ensureExplicitCapacity 方法
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            //判断当前最小适合容量是否大于当前elementData的容量大小
            if (minCapacity - elementData.length > 0)//是否需要扩容的核心代码
                grow(minCapacity);//执行扩容以及copy操作
        }
        
        //grow 方法
        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;//定义old容量的大小
            int newCapacity = oldCapacity + (oldCapacity >> 1);//定义new容量的大小 一般为old容    
                                                               //量的1.5倍
            if (newCapacity - minCapacity < 0)//判断new容量是否小于最小适合容量
                newCapacity = minCapacity;//将最小适合容量大小赋值为new容量
            if (newCapacity - MAX_ARRAY_SIZE > 0)//判断new容量是否大于数组定义的最大size
                newCapacity = hugeCapacity(minCapacity);//判断当前最小适合容量的大小是否超出数组        
                //定义的最大size 若超出返回 Integer.Max_Value 未超出则返回 MAX_ARRAY_VALUE.
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);//执行新数组的copy操作
        }

     

  2. list.addAll 方法实现

        //addAll 方法
         public boolean addAll(Collection<? extends E> c) {
            Object[] a = c.toArray();//定义Object数组a
            int numNew = a.length;//定义numNew
            ensureCapacityInternal(size + numNew);//add方法中的一致,扩容addAll之后新数组的容量
            System.arraycopy(a, 0, elementData, size, numNew);//执行数组的copy方法
            size += numNew;//定义新的elementData.size
            return numNew != 0;
        }

     

  3. list.remove 方法实现

        //remove int
        E remove(int index);
        
        //remove 实现方法
        public E remove(int index) {
            rangeCheck(index);//检测当前index是否超出elementData.size,超出抛出异常 
    
            modCount++;
            E oldValue = elementData(index);//查找对应位置的velue 定义为oldValue
    
            int numMoved = size - index - 1;//定义 移动的位置
            if (numMoved > 0)//判断当前移动的位置是中间还是末尾
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);//消耗性能的原因 中间数据remove 需要从新定义数组执行copy
            elementData[--size] = null; //末尾的直接设置为空
    
            return oldValue;
        }
        //remove Object
        boolean remove(Object o);
    
        //实现方法 建议优先选择remove(int index) 执行remove 操作
        public boolean remove(Object o) {
            if (o == null) {//remove 数据 null 操作
                for (int index = 0; index < size; index++) //循环查找定位 执行remove 方法
                    if (elementData[index] == null) {
                        fastRemove(index);//执行的是remove 方法 
                        return true;
                    }
            } else {//remove 非 null 数据操作
                for (int index = 0; index < size; index++) //循环查找定位 执行remove 方法
                    if (o.equals(elementData[index])) {
                        fastRemove(index);//执行的是remove 方法 请看下面的注意事项
                        return true;
                    }
            }
            return false;
        }
        //注意 remove(Object element)方法只在当前集合中按顺序移除一个元素。即使后边还有 与 element     
        //相同的元素。也不再删除。若有需求 请选择 removeAll 方法

     

  4. list.removeAlla方法实现

        //removeAll 方法
        public boolean removeAll(Collection<?> c) {
            Objects.requireNonNull(c);//判断需要remove的数据是否为null
            return batchRemove(c, false);//执行removeAll方法
        }
        
        //batchRemove 方法
        private boolean batchRemove(Collection<?> c, boolean complement) {
            final Object[] elementData = this.elementData;//定义一个final 类型的数据
            int r = 0, w = 0;
            boolean modified = false;
            try {
                for (; r < size; r++)//循环比对
                    //查询当前数组中是否包含需要remove的数据 contains
                    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;
        }
    
        //contains 方法 再一次循环了一次elementData[] 性能消耗原因 复杂程度 O(m*n)
        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;
        }

     

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章