ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

ArrayList源码解析

2022-04-13 20:35:12  阅读:148  来源: 互联网

标签:index minCapacity int ArrayList elementData 源码 数组 长度 解析


1.无参构造方法

    //默认初始长度
    private static final int DEFAULT_CAPACITY = 10;

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


    //共享空数组 和 EMPTY_ELEMENTDATA 区分用来查看扩容多少
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    //list存储数据的数组
    transient Object[] elementData;

   //list长度
    private int size;


  public ArrayList() {
    //无参构造直接将 初始空数组 赋值给 存值数组
       this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
  }

2.有参构造

public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            //设置的长度大于0,就根据输入的长度创建一个数组给 存值数组
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
           //传入的长度等于0将 共享空数组给 存值数组
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
        //传入负数抛出异常
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }    

3.add方法

/**
 * e 传入的参数
 */
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

 /**
  * minCapacity 当前数组长度+1
  */
 private void ensureCapacityInternal(int minCapacity) {
       ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
 }

/**
 *elementData 存值数组
 *minCapacity 当前数组长度+1
 */
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    //判断 存值数组 是 空数组的话
     if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
          //放入初始容量 和 当前数组长度+1 值进行对比 返回数大的
      return Math.max(DEFAULT_CAPACITY, minCapacity);
      }
      //当 存值数组 不为空的话 返回 当前数组长度+1的值
      return minCapacity;
}

/**
 *minCapacity 返回的最大长度
 */
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        //返回的最大长度 减去存值数组长度 大于0的话 标识需要扩容
        if (minCapacity - elementData.length > 0)
            //调用扩容方法
            grow(minCapacity);
    }

/**
 *minCapacity 需要扩容的长度
 */
 private void grow(int minCapacity) {
        // 将当前数组长度给 oldCapacity
        int oldCapacity = elementData.length;
        //当前将数组长度转为二进制 并向右移动一位 转为16进制 加上原来的长度 得到新的长度
     //例如:第一次扩容的时候长度是 10 十进制转为二进制 1010 向右移动一位是 101 二进制转为10进制 为5 用5加上原来的长度10 等于15
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //新长度 减去 需要扩容的长度 小于0
        if (newCapacity - minCapacity < 0)
            //将需要扩容的长度给新长度
            newCapacity = minCapacity;
     //判断新长度是否大于最大长度 最大长度为 int的最大长度-8 int的最大长度为 2正128
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //将 存值数组 和 扩容长度放入 复制出一个新的数组给 存值数组
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

 

 

4.get方法

public E get(int index) {
        rangeCheck(index);
        return elementData(index);
}

//判断下标是否大于等于数组长度,是的话抛出数组越界
private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

5.set方法

public E set(int index, E element) {
    //判断下标是否越界
    rangeCheck(index);

    E oldValue = elementData(index);
    //将新的给下标
    elementData[index] = element;
    //返回旧的值 
  return oldValue;
}

private void rangeCheck(int index) {
    if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
//获取对应下标的值
E elementData(int index) {
    return (E) elementData[index];
}

6.remove方法

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 rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }

 E elementData(int index) {
return (E) elementData[index];
}
 

 

标签:index,minCapacity,int,ArrayList,elementData,源码,数组,长度,解析
来源: https://www.cnblogs.com/HQ0422/p/16141555.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有