集合容器-LinkedList

LinkedList流程图

LinkedList源码

step1:new LinkedList();
初始化

 /**
 * Constructs an empty list.
 */
public LinkedList() {
}

step2:list.add(obj)
新增元素

/**
 * 链表元素对象结构
 */
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;
    }
}

/**
 * Appends the specified element to the end of this list.
 *
 * @param e element to be appended to this list
 * 
 * 新增元素
 */
public boolean add(E e) {
    linkLast(e);
    return true;
}

/**
 * Links e as last element.
 * 将新添加元素e作为链表的最后一个元素,并维护进去
 */
void linkLast(E e) {
	//获取last节点
    final Node<E> l = last;
    //构建新节点
    final Node<E> newNode = new Node<>(l, e, null);
    //将last指针指向当前节点
    last = newNode;
    //校验是否是第一个节点
    if (l == null){
    	//如果是第一个添加的元素,则first指针指向该节点
        first = newNode;
    } else{
    	//如果不是第一个添加的元素,则更新l的后置节点指向新添加的元素节点
        l.next = newNode;
    }
    //链表长度加1
    size++;
    //链表修改次数加1
    modCount++;
}

step3:list.remove()
移除元素

/**
 * Retrieves and removes the head (first element) of this list.
 *
 * @return the head of this list
 * @throws NoSuchElementException if this list is empty
 * @since 1.5
 */
public E remove() {
	//移除头节点
    return removeFirst();
}

/**
 * Removes and returns the first element from this list.
 *
 * @return the first element from this list
 * @throws NoSuchElementException if this list is empty
 */
public E removeFirst() {
	//获取头节点
    final Node<E> f = first;
    //校验头节点是否为空
    if (f == null)
    	//若为空,则抛出异常
        throw new NoSuchElementException();
    return unlinkFirst(f);
}

/**
 * Unlinks non-null first node f.
 * 解绑头节点
 */
private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
    //获取 f节点的element
    final E element = f.item;
    //获取next指针指向的下一个节点
    final Node<E> next = f.next;
    //将 f节点设为null
    f.item = null;
    //将 f节点的next指针指向null
    f.next = null; // help GC
    //将first指针指向原本的next节点
    first = next;
    //校验next是否为null
    if (next == null){
    	//若next节点为null,将last指针指向null
        last = null;
    }else{
    	//若next节点不为空,将next节点的前置指针指向null,即将next节点变为头节点
        next.prev = null;
    }
    //链表长度减1
    size--;
    //链表修改次数加1
    modCount++;
    //返回 f节点的元素
    return element;
}

step4:list.remove(index)
根据下标移除元素

/**
 * 
 */
public E remove(int index) {
	//校验下标是否越界
    checkElementIndex(index);
    //断开待删除节点的链接,并返回该节点
    return unlink(node(index));
}

/**
 * 校验下标是否越界
 */
private void checkElementIndex(int index) {
    if (!isElementIndex(index))
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

/**
 * Tells if the argument is the index of an existing element.
 * 校验下标是否越界,与ArrayList不同,是否越界需要自己判断
 */
private boolean isElementIndex(int index) {
    return index >= 0 && index < size;
}
/**
 * Returns the (non-null) Node at the specified element index.
 * 根据传入的index,返回对应的节点node
 */
Node<E> node(int index) {
    // assert isElementIndex(index);
	//如果需要获取的index小于总长度size的一半,则从头部开始向后遍历查找
    if (index < (size >> 1)) {
    	//从头部开始向后查找
        Node<E> x = first;
        for (int i = 0; i < index; i++){
        	//从first节点向后next查找,直到index下标node,然后返回
            x = x.next;
        }
        return x;
    } else {
    	//从尾部开始向前遍历查找
        Node<E> x = last;
        for (int i = size - 1; i > index; i--){
        	//从last节点向前prev查找,直到index下标node,然后返回
            x = x.prev;
        }
        return x;
    }
}

/**
 * Unlinks non-null node x.
 * 从链表中删除 x节点的链接
 */
E unlink(Node<E> x) {
    // assert x != null;
    //获取x节点的元素,前置节点,后置节点
    final E element = x.item;
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;
	//校验x节点是否为第一个节点,x.prev为null,表示x节点为第一个节点
    if (prev == null) {
    	//若是第一节点,则将first头指针指向x节点的后置节点
        first = next;
    } else {
    	//若不是第一节点,将x节点前置节点的后置指针指向x节点的后置节点
        prev.next = next;
        //断开x节点的前置指针,将x节点的前置指针指向null
        x.prev = null;
    }
	//校验x节点是否为末节点,x.next为null,标识x节点为末节点
    if (next == null) {
    	//若是末节点,将last指针指向x节点的前置节点
        last = prev;
    } else {
    	//若不是末节点,将x节点后置节点的前置指针指向x节点的前置节点
        next.prev = prev;
        //断开x节点的后置指针,将x节点的后置指针指向null
        x.next = null;
    }
	//将x节点的element设置为null
    x.item = null;
    //链表长度减1
    size--;
    //链表修改长度加1
    modCount++;
    //返回x节点的element
    return element;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值