zoukankan      html  css  js  c++  java
  • ArrayList 源码分析 基于jdk1.8:

    1:数据结构:

    transient Object[] elementData;  //说明内部维护的数据结构是一个Object[] 数组

       成员属性:

    private static final int DEFAULT_CAPACITY = 10;  

    private static final Object[] EMPTY_ELEMENTDATA = {};  //空数组

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //默认空数组

    transient Object[] elementData;  //维护数组的引用

    private int size;   //数组长度

    2:构造方法:

    public ArrayList() {

            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; //构造长度为0的Object[]  赋值给elementData,用于后面保存数据

    }

    3:主要方法的分析: add  get   remove  add(int index,Object o)

    1)       add:  以添加第一个元素为例

       public boolean add(E e) { e=”aa”

            ensureCapacityInternal(size + 1);  // size=0

            elementData[size++] = e;

            return true;

    }

    private void ensureCapacityInternal(int minCapacity) {  // minCapacity=1

            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //第一个元素 true

                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //取 DEFAULT_CAPACITY

            }

            ensureExplicitCapacity(minCapacity);

        }

    下面进入ensureExplicitCapacity 分析

    private void ensureExplicitCapacity(int minCapacity) {

            modCount++;

            // overflow-conscious code

            if (minCapacity - elementData.length > 0)  //10-0=10

                grow(minCapacity);  //进入扩容的方法

        }

    以下是扩容的方法:

    private void grow(int minCapacity) {  // minCapacity=10

            // overflow-conscious code

            int oldCapacity = elementData.length;  // oldCapacity=0

            int newCapacity = oldCapacity + (oldCapacity >> 1);  //移位操作,移位后newCapacity=0

            if (newCapacity - minCapacity < 0)   //0-10=-10

                newCapacity = minCapacity;    // newCapacity=10

            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); //将旧数组中的内容拷贝到新的数组中  并且将新的数组赋值给elementData

        }

    扩容机制:

    int newCapacity = oldCapacity + (oldCapacity >> 1);  //将新数组扩容为原先数组的1.5倍长度

    2):add(int index,Object o)方法分析

    主要的实现方法如下:

    public void add(int index, E element) {  // index1

            rangeCheckForAdd(index);   //和add方法里的一直

            ensureCapacityInternal(size + 1);  //和add方法里的一直

            System.arraycopy(elementData, index, elementData, index + 1,

                             size - index);  //主要是这里实现的index后面元素的拷贝

            elementData[index] = element;

            size++;

        }

    下面分析这句代码实现的效果

    System.arraycopy(elementData, index, elementData, index + 1,

                             size - index);

    原始数组的结构和数据:

     
       

    System.arraycopy方法执行后的数据结构 将 b2,b3 往后复制元素

     
       

     

    最后将index处的元素赋值

    elementData[index] = element;

    这就是在具体索引进行add 的方法,往后的元素进行拷贝,导致消耗比较大

    3):get方法:

    public E get(int index) {

            rangeCheck(index);   //检查数组是否越界

            return elementData(index); //返回数组的index 索引出的元素

        }

    Get 方法比较简单,就不做过多分析了

  • 相关阅读:
    设计模式
    常用数据结构及复杂度 array、LinkedList、List、Stack、Queue、Dictionary、SortedDictionary、HashSet、SortedSet
    在 ASP.NET MVC 项目中使用 WebForm、 HTML
    二分法 数据必须是排序好的
    location.href IE6 下不起作用的罪魁祸首
    leetcode 372. Super Pow
    turple list dict 互相转换
    Pandas之Dropna滤除缺失数据
    模型选择---KFold,StratifiedKFold k折交叉切分
    xgb, lgb, Keras, LR(二分类、多分类代码)
  • 原文地址:https://www.cnblogs.com/beppezhang/p/11214479.html
Copyright © 2011-2022 走看看