ArrayList从0到1

ArrayList其实就是一个长度可变的数组,初始其实是空数组,当添加第一个元素的时候数组容量才变成10
插入删除元素的时间复杂度为O(n),求表长以及增加元素,取第 i 元素的时间复杂度为O(1)

1.ArrayList的数据结构

//使用一个Object数组进行存储
 transient Object[] elementData;
 //数组元素的大小
 private int size;

2.add方法

1.无指定下标的add方法

以下的JDK源码

	//增加方法
   public boolean add(E e) {
    
    
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    //检查是否要扩容
    private void ensureCapacityInternal(int minCapacity) {
    
    
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
    //得到最小扩容量
  	private static int calculateCapacity(Object[] elementData, int minCapacity) {
    
    
  		//返回默认容量和当前容器加1的最大值
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    
    
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
    //判断是否需要扩容
	 private void ensureExplicitCapacity(int minCapacity) {
    
    
        modCount++;
        //容量超出即扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    //扩容
   private void grow(int minCapacity) {
    
    
   		//保存旧容量
        int oldCapacity = elementData.length;
        //新容量为旧容量的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //新容量是否小于最小需要容量
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
         //新容量是否超出了ArrayList所定义的最大容量
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
          //拷贝,ArrayscopyOf()继续调用System的arraycopy
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

总结:
1、先判断是否扩容再赋值
2、扩容为原来数组的1.5倍
3、使用System的拷贝方法

2.指定下标的add方法

   public void add(int index, E element) {
    
    
       //检查下标是否越界
        rangeCheckForAdd(index);
        //判断是否要扩容
        ensureCapacityInternal(size + 1);  
        //让index开始之后的所有成员后移一个位置:
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

remove方法和get方法类似,只不过是删除元素并且左移

猜你喜欢

转载自blog.csdn.net/weixin_40791454/article/details/107040140