我的ArrayList源码理解

送分小仙女□ 提交于 2019-12-23 09:03:55

ArrayList源码理解

  • ArrayList底层使用 动态数组 并且 默认初始容量为10,空的数组为{}

    private static final int DEFAULT_CAPACITY = 10; 
    transient Object[] elementData;
    private static final Object[] EMPTY_ELEMENTDATA = {};  
    
  • 获取元素、修改元素

        //    获取数组下标的元素
        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) {
        	//    容量+1
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            //    然后将值赋值给最后一个
            elementData[size++] = e;
            return true;
        }
        
        //    按下标添加元素
        public void add(int index, E element) {
        	//    检查下标是否越界
            rangeCheckForAdd(index);
            //    容量+1
            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;    //    返回移除的数据
        }
        
        //    移除指定下标的数据
        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 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 grow(int minCapacity) {
            // overflow-conscious code
        	//    获取数组的旧值
            int oldCapacity = elementData.length;
            //    创建新值 是旧值的1.5倍
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            //    如果新值小于传入值 则新值等于传入值
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            //    如果新值大于0x7fffffff-8 则新值等于0x7fffffff
            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);  //    创建扩容后的数组
        }
    
  • ArrayList底层获取大小和判断是否为空

        //    返回大小
        public int size() {
            return size;
        }
    
        //    判断是否为空
        public boolean isEmpty() {
            return size == 0;
        }
    
  • ArrayList获取元素下标、从后面获取元素下标、判断是否包含元素

        //    返回传入元素下标
        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;
            }
            //    查找不到元素是返回 -1
            return -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;
            }
            //    查找不到返回 -1
            return -1;
        }
        
        //    判断是否包含传入元素
        public boolean contains(Object o) {
            return indexOf(o) >= 0;
        }
    
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!