ArrayList源码分析

目录

 

ArrayList底层是采用数组

ArrayList构造函数

ArrayList add分析

ArrayList Get分析

ArrayList Remove分析

LinkedList底层是链表

LinkedList构造函数

LinkedList add分析

LinkedList Remove分析

LinkedList Get分析


ArrayList底层是采用数组

ArrayList构造函数

并未开辟空间,将elementData设置为空{ }

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

ArrayList add分析

初次add 会将开辟一个长度为10的数组,之后每次添加,size+1为需要的容量,如果需要的容量>数组现在的长度

则数组需要再次扩容,按1.5倍扩容

比如:从add 1到add15中,add 1时候数组开辟,之后add 2到10时候

需要的容量<=数组长度10,此期间都不需要扩容,当add 11时,需要的容量11>数组长度10,此时数组扩容到15,

当add 12..15时,均不需扩容,add 16是再次按照1.5倍扩容...........

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) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//初次扩容
        return Math.max(DEFAULT_CAPACITY, minCapacity);//初始容量为10,DEFAULT_CAPACITY,返回10
    }
    return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {//参数为需要的最小容量
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)//如果需要的容量>数组实际容量则需要扩容
        grow(minCapacity);
}
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);//1.5倍扩容
    if (newCapacity - minCapacity < 0)//
        newCapacity = minCapacity;
    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 Get分析

public E get(int index) {
    rangeCheck(index);

    return elementData(index);//直接返回
}

ArrayList 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);//从数组中index+1位置开始移动numMoved个到
//数组中index开始的位置
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

LinkedList底层是链表

 

LinkedList构造函数

public LinkedList() {//什么也没干
}

LinkedList add分析

初次add新节点,将新节点设置为头节点和尾节点,再次add,则将新节点链接到链表最后(尾节点后面)
 

public boolean add(E e) {
    linkLast(e);
    return true;
}

void linkLast(E e) { final Node<E> l = last;//获取到最后一个元素, 
final Node<E> newNode = new Node<>(l, e, null); last = newNode;//新节点作为尾节点 
if (l == null)//如果没添加前的尾节点是null,代表链表还没有元素,则尾节点也是头结点 
    first = newNode; 
else  //如果没添加前的尾节点不是null,则把添加前的尾节点的后面链上新的尾节点 
    l.next = newNode; size++; modCount++; 
}

LinkedList Remove分析

public E remove(int index) {
    checkElementIndex(index);
    return unlink(node(index));//通过node(index)寻找到要删除的节点
}
 */
E unlink(Node<E> x) {
    // assert x != null;
    final E element = x.item;
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;

    if (prev == null) {//删除的是头结点
        first = next;
    } else {//不是头结点,就将上一个节点链接上要删除的节点的next节点
        prev.next = next;
        x.prev = null;
    }

    if (next == null) {//删除的节点是尾节点
        last = prev;
    } else {//不是尾节点,则将next节点的前指针指向要删除的节点的prev
        next.prev = prev;
        x.next = null;
    }

    x.item = null;
    size--;
    modCount++;
    return element;
}

LinkedList Get分析

此时的index并非是真正意义上的下标,而是放入链表中的顺序,序号 get(4) 代表获取放入链表中的第4个元素

public E get(int index) {
    checkElementIndex(index);
    return node(index).item;
}
Node<E> node(int index) {//如果index是链表总长度的一半多,则从尾部开始寻找,不够一半则从头结点开始寻找,一直到index位置取出
    // assert isElementIndex(index);

    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值