Java-第十五部分-源码解读-ArrayList和LinkedList

228 阅读2分钟

源码解读全文

ArrayList

  • 迭代器设计模式
  • 数组结构,需要扩容(1.5倍),迁移元素复制一份
  • 线程不安全的

扩容

  • add
public boolean add(E e) {
    //size++
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
  • ensureCapacityInternal 确保容量
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
  • calculateCapacity 如果是空的,返回默认值或者最小值中大的那一个
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        //默认初始化为10
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
  • ensureExplicitCapacity 给list扩容
private void ensureExplicitCapacity(int minCapacity) {
    modCount++; //记录修改的次数

    // overflow-conscious code
    //传入的size比当前数组长度要大,进行扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
  • grow 增加为1.5倍,并复制一份
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity; //如果还小,那就为传入的size
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        //MAX_ARRAR_SIZE 为 Integer.MAX_VALUE - 8
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    //复制一份
    elementData = Arrays.copyOf(elementData, newCapacity);
}

remove

public E remove(int index) {
    rangeCheck(index); //检查是否越界
    modCount++;
    E oldValue = elementData(index);
    //后面元素的长度 size5 remove2 那么 0 1 2 3 4 后面的长度为 2 = 5 - 2 - 1
    int numMoved = size - index - 1;
    if (numMoved > 0)
        //把后面的元素往前移动,复制到前面
        //从idx+1开始的元素 复制到idx 复制numMoved长
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    //设置结束元素为null
    elementData[--size] = null; // clear to let GC do its work
    return oldValue;
}
  • elementData获取元素
E elementData(int index) {
    return (E) elementData[index];
}

get

public E get(int index) {
    rangeCheck(index); //检查是否越界

    return elementData(index);
}

size

public int size() {
    return size;
}

LinkedList

  • 双向链表结构,不需要扩容,遍历时先除2,找到大致位置
  • 线程不安全

Node

  • 双向链表
private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

add

  • 将待添加元素,放到末尾
public boolean add(E e) {
    linkLast(e);
    return true;
}
  • linkLast
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 //连接
        l.next = newNode;
    size++;
    modCount++;
}
  • linkFirst头插法
private void linkFirst(E e) {
    final Node<E> f = first;
    final Node<E> newNode = new Node<>(null, e, f);
    first = newNode;
    if (f == null)
        last = newNode;
    else
        f.prev = newNode;
    size++;
    modCount++;
}

offer

  • 实际上就是调用add方法
public boolean offer(E e) {
    return add(e);
}
  • offerFirst头插法
public boolean offerFirst(E e) {
    addFirst(e);
    return true;
}
  • offerLast尾插法
public boolean offerLast(E e) {
    addLast(e);
    return true;
}

push

  • 什么都不返回
public void push(E e) {
    addFirst(e);
}

get

public E get(int index) {
    checkElementIndex(index); //越界异常
    return node(index).item;
}
  • node找节点
Node<E> node(int index) {
    if (index < (size >> 1)) { //如果小于size两倍,那么在前半部分
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else { //大于size两倍,在后半部分
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

poll

  • 没有则返回null
public E poll() {
    final Node<E> f = first;
    return (f == null) ? null : unlinkFirst(f);
}
  • unlinkFirst获取头节点
private E unlinkFirst(Node<E> f) {
    final E element = f.item;
    final Node<E> next = f.next;
    f.item = null; //帮助gc 防止内存泄漏
    f.next = null; // help GC
    first = next; //更新头节点
    if (next == null) //维护空的情况
        last = null;
    else
        next.prev = null;
    size--; //维护长度
    modCount++;
    return element;
}

pop

  • 没有则抛异常
public E pop() {
    return removeFirst();
}
  • removeFirst null抛异常
public E removeFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}

remove

public E remove(int index) {
    checkElementIndex(index); //越界检查
    return unlink(node(index)); //找到响应的node,并移除
}
  • unlink
E unlink(Node<E> x) {
    final E element = x.item;
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;
    if (prev == null) { //处理是头的情况
        first = next;
    } else {
        prev.next = next;
        x.prev = null;
    }
    if (next == null) { //处理是尾的情况
        last = prev;
    } else {
        next.prev = prev;
        x.next = null;
    }
    x.item = null; //帮助gc
    size--;
    modCount++;
    return element;
}

size

public int size() {
    return size;
}