jdk10 ArrayList阅读笔记

构造函数

/**
 *elementData 是内部存放数据的数字,
 *DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是用来标识无参构造函数空数组的一个final对象
 *无参构造函数中,将DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的引用赋值给了elementData
 **/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

/**
 *EMPTY_ELEMENTDATA 是用来标识有参构造函,且入参为空数空数组的一个final对象。
 *EMPTY_ELEMENTDATA 与DEFAULTCAPACITY_EMPTY_ELEMENTDATA的区别在于后续会根据他们来判断膨胀的速度
 *有参构造函数中,将EMPTY_ELEMENTDATA 的引用赋值给了elementData
 **/
private static final Object[] EMPTY_ELEMENTDATA = {};

/**
 *如果initialCapacity > 0,那么elementData等于一个Object数组,长度为入参;否则等于EMPTY_ELEMENTDATA
 **/
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

/**
 *elementData 等于入参toArrayList,size等于入参长度,elementData 等于EMPTY_ELEMENTDATA
 **/
public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // defend against c.toArray (incorrectly) not returning Object[]
        // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

添加操作

/**
 *修改次数加一
 **/
public boolean add(E e) {
    modCount++;
    add(e, elementData, size);
    return true;
}
/**
 *如果elementData的长度等于size,说明数组满额了,那么执行扩容。elementData[s] = 要插入的元素,size加一
 **/
private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    size = s + 1;
}

/**
 *以size+1为最小容量的扩容(要放下这个元素嘛)
 **/
private Object[] grow() {
 return grow(size + 1);
}

private Object[] grow(int minCapacity) {
  return elementData = Arrays.copyOf(elementData,newCapacity(minCapacity));
}

/**
 *newCapacity等于原容量+原容量整除2,差不多1.5倍
 *因为是位运算,原容量等于0的时候,新容量也是0。
 *如果elementData 等于DEFAULTCAPACITY_EMPTY_ELEMENTDATA,也就是无参构造函数构建的,那么取DEFAULT_CAPACITY,
 *minCapacity的最大值,在add(E)中,是取 10和1的最大值。
 *还有一种情况:入参为int的那个构造函数,传入0,直接返回minCapacity,在在add(E)中,是1。
 *如果新容量小于MAX_ARRAY_SIZE,那么返回计算出的新容量,否则返回Integer.Max(其实就差8)
 **/
private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity <= 0) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return minCapacity;
    }
    return (newCapacity - MAX_ARRAY_SIZE <= 0)
        ? newCapacity
        : hugeCapacity(minCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE)
        ? Integer.MAX_VALUE
        : MAX_ARRAY_SIZE;
}

读取操作

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

private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

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

很简单,检查一下是否越界,然后从数组中取到这个值并返回

删除操作

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;
}

修改次数增加,计算位移的元素数量。如果位移数量大于零,那么将index+1以及之后的数据,复制到index到之后的位置。将多出来的尾元素置为null,然后size–

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值