简单了解LinkedList源码

LinkedList
实现的原理应该是双链表,因为空链表的情况应该是header节点的前一节点和后一节点均为null。如果是循环链表,空链表应该头节点的头尾指针指向自己 。
首先注意链表的数据结构写法

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

1.LinkedList linkedList = new LinkedList();
有两个构造器,默认构造器为空,带参构造器无非调用addAll()方法

2.linkedList.add(1);

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
        l.next = newNode;//修改后继指针
    size++;
    modCount++;
}   

3.linkedList.addAll(linkedList1);

public boolean addAll(Collection<? extends E> c) {
    return addAll(size, c);
}  

   public <T> T[] toArray(T[] a) {
    if (a.length < size)
        a = (T[]) java.lang.reflect.Array.newInstance(
                a.getClass().getComponentType(), size);
    int i = 0;
    Object[] result = a;
    for (Node<E> x = first; x != null; x = x.next) //修改指针遍历
        result[i++] = x.item;

    if (a.length > size)
        a[size] = null;

    return a;
}

public boolean addAll(int index, Collection<? extends E> c) {
    checkPositionIndex(index);

    Object[] a = c.toArray(); //遍历将节点赋值到数组中
    int numNew = a.length;  //新数据的长度
    if (numNew == 0)
        return false;

    Node<E> pred, succ;
    if (index == size) {//肯定相同
        succ = null;
        pred = last;
    } else {
        succ = node(index);
        pred = succ.prev;
    }

    for (Object o : a) {//遍历数组,修改原数组的最后一个节点的指针
        @SuppressWarnings("unchecked") E e = (E) o;
        Node<E> newNode = new Node<>(pred, e, null);
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        pred = newNode;
    }

    if (succ == null) {
        last = pred;
    } else {
        pred.next = succ;
        succ.prev = pred;
    }

    size += numNew;
    modCount++;
    return true;
}  

4. linkedList.set(1,1);

public E set(int index, E element) {
    checkElementIndex(index);
    Node<E> x = node(index);
    E oldVal = x.item;
    x.item = element;
    return oldVal;
}

Node<E> node(int 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;
    }
}

5. linkedList.remove();

public E remove() {
    return removeFirst();
}

//很明显要删除第一个节点
public E removeFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}
//修改指针执行,并置空
private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
    final E element = f.item;
    final Node<E> next = f.next;
    f.item = null;
    f.next = null; // help GC
    first = next;
    if (next == null)
        last = null;
    else
        next.prev = null;
    size--;
    modCount++;
    return element;
}

6.get();

public E get(int index) {
    checkElementIndex(index);
//还是老套路,根据索引遍历到节点
    return node(index).item;
}   

7.linkedList.indexOf(1)

public int indexOf(Object o) {
    int index = 0;
    if (o == null) {
        for (Node<E> x = first; x != null; x = x.next) {
            if (x.item == null)
                return index;
            index++;
        }
    } else {
        for (Node<E> x = first; x != null; x = x.next) {
            if (o.equals(x.item))
                return index;
            index++;
        }
    }
    return -1;
}

8.linkedList.remove(0)

public E remove(int index) {
    checkElementIndex(index);
    return unlink(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 {
        prev.next = next;
        x.prev = null;
    }

    if (next == null) {
        last = prev;
    } else {
        next.prev = prev;
        x.next = null;
    }

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

9. linkedList.clear();

public void clear() {

    for (Node<E> x = first; x != null; ) {
        Node<E> next = x.next;
        x.item = null;
        x.next = null;
        x.prev = null;
        x = next;
    }
    first = last = null;
    size = 0;
    modCount++;
}

猜你喜欢

转载自blog.csdn.net/yuezheyue123/article/details/81068573