zoukankan      html  css  js  c++  java
  • 【Java源码分析】LinkedList类

    LinkedList<E> 源码解读

    继承AbstractSequentialList<E>

    实现List<E>, Deque<E>, Cloneable, Serializable接口

    方法说明

    private void linkFirst(E e)

    功能:将新元素添加至链表的头。

    过程:如果头为空,头尾结点共同指向新结点,反之,把新结点插入到原头结点前。

    void linkLast(E e)

    功能:将新元素添加至链表的尾。

    过程:如果尾为空,头尾结点共同指向新结点,反之,把新结点 插入到原尾结点后。

    void linkBefore(E e, Node<E> succ)

    功能:把新结点插入到目标结点前。

    过程:设置一个临时引用指向succ的前结点,然后把新结点插入到succ结点前结点的后面,succ的前指针重新指向新结点,新结点前指针如果为空,那么头指针指向新结点,否则,新结点的前结点的后指针指向新结点。

    private E unlinkFirst(Node<E> f)

    功能:把头结点删除并返回结点元素值(不能对空链表执行该操作)。

    过程:建立临时结点存储头结点的next指针指向的结点,让头结点的元素值置为空,头结点的next指针指向空,判断如果头结点的next指针指向空,那么尾结点也指向空(即链表为空),否则,让头结点的next指针指向的结点(最开始存入临时结点)的前指针指向空。

    private E unlinkLast(Node<E> l)

    功能:把尾结点删除并返回结点元素值(不能对空链表执行该操作)。

    过程:建立临时结点存储尾结点的prev指针指向的结点,让尾结点的元素值置为空,尾结点的prev指针指向空,判断如果尾结点的prev指针指向空,那么头结点也指向空(即链表为空),否则,让尾结点的prev指针指向的结点(最开始存入临时结点)的后指针指向空。

    E unlink(Node<E> x)

    功能:删除一个结点,并返回该结点的元素值(不能对空链表执行该操作)。

    过程:建立两个临时的结点的引用,分别指向目标结点的头指针指向的结点和后指针指向的结点。判断如果目标结点前指针不为空,那么临时的结点引用prev的后指针指向临时的结点引用next指向的结点,否则,原头指针指向临时结点引用next所指向的结点,然后把目标结点的前指针指向空。对目标结点的后指针同样进行判断操作,然后把目标结点的后指针指向空。最后把目标结点元素置空。

    public E getFirst()

    功能:返回链表第一个结点的元素值。

    过程:判断头结点是否为空,如果为空则抛出NoSuchElementException异常,否则返回头指针指向的结点的元素值。

    public E getLast ()

    功能:返回链表最后一个结点的元素值。

    过程:判断尾结点是否为空,如果为空则抛出NoSuchElementException异常,否则返回尾指针指向的结点的元素值。

    public E removeFirst()

    功能:删除头结点并返回结点元素值。

    过程:判断头结点是否为空,如果为空则抛出NoSuchElementException异常,否则调用unlinkFirst()方法。

    public E removeLast ()

    功能:删除尾结点并返回结点元素值。

    过程:判断尾结点是否为空,如果为空则抛出NoSuchElementException异常,否则调用unlinkLast()方法。

    public void addFirst(E e)

    功能:向链表头添加一个元素。

    过程:调用linkFirst(E e)方法。

    public void addLast(E e)

    功能:向链表尾添加一个元素。

    过程:调用linkLast (E e)方法。

    public boolean contains(Object o)

    功能:判断某个元素是否在链表中。

    过程:调用indexOf()方法,判断返回的索引值是否为-1,如果是则代表链表中不存在该元素索引,则返回false,否则返回true.

    public int size()

    功能:返回链表长度。

    过程:返回LinkedList类中的类私有变量size.

    备注:size在链表进行添加和删除操作时都会相应的增加或减少。

    public boolean add(E e)

    功能:向链表尾部添加一个元素

    过程:调用包权限方法linkLast(E e),并返回true.

    public boolean remove(Object o)

    功能:删除链表中的某个元素。

    过程:判断o是否为空,如果为空则遍历链表,把空元素所在结点用unlink()方法删除,并返回true;反之,也遍历链表,调用equals()方法判断每个结点的元素是否和传入的元素相等,如果是则调用unlink()方法删除,并返回true;如果都没有符合条件的元素,则返回false.

    public boolean addAll(Collection<? extends E> c)

    功能:把一个Collection对象直接添加至链表尾部。

    过程:调用addAll(size, c)并将该方法的返回值直接返回。

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

    功能:把一个Collection对象插入到链表第index元素之后。

    过程:先调用checkPositionIndex方法检测传入的index是否超过链表size,如果是则抛出异常。然后将Collection对象转为Object数组,判断数组长度是否为0,是的话则返回false.然后创建两个结点的引用,分别指向index结点(prev)和index后一结点(succ)(如果后一结点为空则指向空)。然后遍历传入的Collection对象被转成的Object数组,每次建立一个临时的newNode,然后插入之前创建的指针中(prev后,succ前),并返回true.

    public void clear()

    功能:清空链表中所有结点。

    过程:遍历链表,当结点不为空时,建立一个临时结点引用指向下一结点,然后清空当前结点的元素值及prev next指针。最后让first和last指针都指向空,并置size为0.

    public E get(int index)

    功能:根据索引返回指定的结点元素值。

    过程:先调用checkElementIndex()方法检查索引是否超过链表长度,超过则抛出异常。然后返回指定结点元素,调用node()方法的返回制定结点并访问item成员。

    public E set(int index, E element)

    功能:根据指定的索引修改结点中的元素值,并返回之前结点中的元素值。

    过程:先调用checkElementIndex()方法检查索引是否超过链表长度,超过则抛出异常。然后把原先结点的元素的值存储起来,替换后返回原结点的元素值。

    public void add(int index, E element)

    功能:把元素插入到指定索引结点前。

    过程:首先判断索引是否越界,如果是则抛出异常。否则,判断索引是否为最后一个元素之后的元素(即index == size),如果是则调用linkLast()方法,把结点插入最后,否则调用linkBefore()方法,把新结点插入到指定索引结点前。

    public E remove(int index)

    功能:删除指定索引出的结点。

    过程:先调用checkElementIndex()方法判断索引是否越界,是则抛出异常。然后调用unlink()方法将指定结点删除,并返回unlink()的返回值。

    private boolean isElementIndex(int index)

    功能:判断索引值是否大于等于0且小于size,即索引对应的结点是否存在。

    过程:如果小于0或大于等于size则返回false,反之,则返回true.

    private boolean isPositionIndex(int index)

    功能:判断索引值是否大于等于0且小于等于size,即索引位置对于迭代器和add()方法来说是否合法。

    过程:如果小于0或大于size则返回false,反之,则返回true.

    private String outOfBoundsMsg(int index)

    功能:返回索引越界异常的字符串提示信息。

    过程:返回索引越界异常的字符串提示信息。

    private void checkElementIndex(int index)

    功能:如果索引对应结点不存在(index < 0 || index >= size),抛出越界异常。

    过程:调用isElementIndex()方法判断索引是否有对应的结点,如果没有,抛出异常。

    private void checkPositionIndex()

    功能:如果索引不能用于迭代器和add()方法(index < 0 || index > size),抛出越界异常。

    过程:调用isPositionIndex()方法判断索引是否有对应的结点,如果没有,抛出异常。

    Node<E> node(int index)

    功能:返回索引对应的结点。

    过程:先判断index与size右移一位后(>>1即除以2)后,如果index在左半部分,则从head结点开始遍历,如果index在右半部分,则从last结点向前开始遍历。

    private int indexOf(Object o)

    功能:返回对应的o所在结点的索引值,如果有重复则返回第一个结点对应的索引值,如果不存在则返回-1.

    过程:判断o是否为空,分为空或非空的分支情况然后从first结点遍历链表,若没有找到则返回-1.

    private int lastIndexOf(Object o)

    功能:返回对应的o所在结点的索引值,如果有重复则返回最后的一个结点的索引值,如果不存在则返回-1.

    过程:判断o是否为空,分为空或非空的分支情况然后从last结点遍历链表,若没有找到则返回-1.

    LinkedList模拟Queue方法

    public E peek()

    功能:返回头结点的元素值。

    过程:判断头结点是否为空,为空则返回空,否则返回头结点对应元素。

    public E element()

    功能:返回头结点的元素值,如果为空则抛出异常。

    过程:调用getFirst()方法,并将getFirst()方法的返回值返回。

    public E poll()

    功能:删除头结点。

    过程:删除头结点,如果头为空则返回空,否则调用unlinkFirst()方法并返回该方法的返回值。

    public E remove()

    功能:删除头结点,如果头结点为空则抛出异常。

    过程:调用removeFirst()方法并返回该方法的返回值。

    public boolean offer(E e)

    功能:添加一个结点至链表尾部。

    过程:调用add()方法。

    LinkedList模拟Deque方法

    public boolean offerFirst(E e)

    功能:添加一个结点至链表头部。

    过程:调用addFirst()方法并返回true.

    public boolean offerLast(E e)

    功能:添加一个结点至链表尾部。

    过程:调用addLast()方法并返回true.

    public E peekFirst()

    功能:返回头结点的元素值,如果为空则返回空。

    过程:判断头结点是否为空,如果为空则返回null,否则返回头结点元素值。

    public E peekLast()

    功能:返回尾结点的元素值,如果为空则返回空。

    过程:判断尾结点是否为空,如果为空则返回null,否则返回尾结点元素值。

    public E pollFirst()

    功能:返回头结点的元素值,如果为空则返回空,否则删除头结点。

    过程:判断头结点是否为空,如果为空则返回null,否则调用unlinkFirst()并返回该方法的返回值。

    public E pollLast()

    功能:返回尾结点的元素值,如果为空则返回空,否则删除尾结点。

    过程:判断尾结点是否为空,如果为空则返回null,否则调用unlinkLast()方法并返回该方法的返回值。

    public void push(E e)

    功能:把一个元素添加到链表的头。

    过程:调用addFirst()方法。

    public E pop()

    功能:删除头结点并返回头结点元素值,如果为空链表则抛出异常。

    过程:调用removeFirst()并返回该方法的返回值。

    public boolean removeFirstOccurrence(Object o)

    功能:删除对应元素第一次出现所在的结点。

    过程:调用remove()方法并返回该方法返回值。

    public boolean removeLastOccurrence(Object o)

    功能:删除对应元素最后一次出现所在的结点。

    过程:判断o是否为空,分两种情况分别操作。从链表尾部向前遍历链表,遇到第一个符合条件的结点时调用unlink()方法删除,并返回true.如果没有符合条件的结点,则返回false.

    Iterator操作

    public ListIterator<E> ListIterator(int index)

    功能:返回对应索引的迭代器。如果索引越界则抛出异常。

    过程:调用checkPositionIndex(index),然后返回一个ListItr(此类中的内部类)的实例。

    内部类private class ListItr implements ListIterator<E>

    私有成员变量:

    private Node<E> lastReturned;

    private Node<E> next;

    private int nextIndex;

    private int expectedModCount = modCount;

    方法:

    ListItr(int index)

    功能:带参数的构造器。初始化next结点为索引对应链表中的结点,如果为空则返回空。初始化nextIndex为index.

    过程:判断index是否等于size,如果等于则复制next为空,否则调用node()方法把索引对应的结点让next引用指向。最后把index赋值nextIndex.

    public boolean hasNext()

    功能:判断链表是否有下一结点。

    过程:返回nextIndex < size结果。

    public E next()

    功能:判断迭代过程中是否对链表对象进行更改,如果有则抛出异常。然后判断是否有下个元素,如果没有抛出异常。然后返回迭代器指向的下一结点的元素值,然后把迭代器指向下一位。

    过程:调用checkForComodification()方法检查在迭代过程中是否对链表对象进行操作(只能使用迭代器提供的方法对链表进行操作),然后调用hasNext()方法判断是否有下一结点,如果没有抛出NoSuchElementException()异常。最后使用内部类成员变量lastReturned指向next指向的结点位置,然后让next引用指向后一结点对象,为nextIndex进行加一操作,返回lastReturned的元素值。

    public boolean hasPrevious()

    功能:判断当前结点是否还有前结点。

    过程:返回nextIndex > 0结果(nextIndex为初始化是传递进来的索引值)。

    public E previous()

    功能:判断迭代过程中是否对链表对象进行更改,如果有则抛出异常。然后判断是否有上个元素,如果没有抛出异常。然后返回迭代器指向的上一结点的元素值,然后把迭代器指向上一位。

    过程:调用checkForComodification()方法检查在迭代过程中是否对链表对象进行操作(只能使用迭代器提供的方法对链表进行操作),然后调用hasPrevious()方法判断是否有下一结点,如果没有抛出NoSuchElementException()异常。最后使用内部类成员变量lastReturned指向next指向的结点位置,然后让next引用指向前一结点对象(为空则置空),为nextIndex进行减减操作,返回lastReturned的元素值。

    public int nextIndex()

    功能:返回当前结点的索引值。

    过程:返回nextIndex.

    public int previousIndex()

    功能:返回前一结点的索引值。

    过程:返回nextIndex – 1.

    public void remove()

    功能:判断是否在迭代过程中使用非迭代器方法对链表进行操作了(会对链表长度产生变化),如果有则抛出异常。然后判断迭代器是否移动了,如果未移动则抛出异常。然后删除迭代器移动之前所指向结点。

    过程:调用checkForComodification()方法判断迭代过程中是否有非迭代器方法对链表长度改变的操作,然后判断lastReturned是否为空,即是否使迭代器位置发生改变。如果未发生改变则抛出异常。然后把lastReturned的下一结点赋值给临时结点引用,调用unlink()方法删除目标结点(迭代器移动前所指向的结点),如果要删除的结点是尾结点,那么next结点引用指向被删结点的next指向结点,否则,nextIndex计数器减减操作。

    public void set(E e)

    功能:把上一次迭代器改变位置的结点置新值。

    过程:判断lastReturned变量是否为空来判断迭代器是否移动过,如果没有移动过则抛出异常,然后调用checkForComodification()方法判断是否有非迭代器方法改变了链表长度,如果有则抛出异常。然后把lastReturned结点的item值更换为传递过来的引用。

    public void add(E e)

    功能:如果迭代器移动过,则把新元素添加到迭代器上次指向的结点之后。

    过程:调用checkForComodification()判断迭代器是否移动过,如果上次移动的位置是结尾,则调用linkLast()方法把元素添加至链表尾部,否则调用linkBefore()方法把元素添加至目标结点后。

    public void foreachRemaining(Consumer<? super E> action)

    暂时不明确该方法使用方法及实现过程。

    final void checkForComodification()

    功能:判断是否有非迭代器方法使得链表长度发生改变。

    过程:比较modCount和expectedModCount变量,如果在迭代期间调用了操作链表长度的非迭代器内方法,则modCount值会与expectedModCount不同步,抛出异常。

    内部类private static class Node<E>

    成员变量:E item;          代表一个结点的元素值。泛型E表示。

                         Node<E> next;              代表指向下一结点的引用。

                         Node<E> prev;              代表指向前一结点的引用。

    Node(Node<E> prev, E element, Node<E> next)

    含参构造器,用于初始化。

    迭代器方法

    public Iterator<E> descendingIterator()

    功能:返回一个逆向迭代器的对象。

    过程:返回一个DescendingIterator实例。

    内部类 private class DescendingIterator implements Iterator<E>

    成员变量:private final ListItr itr = new ListItr(size());

    建立一个迭代器的实例,让其初始指向链表尾部。

    public boolean hasNext()

    功能:判断是否有前驱结点并返回真假。

    过程:调用ListItr内部类中hasPrevious()方法并返回其返回值。

    public E next()

    功能:返回前驱结点的元素值。

    过程:调用ListItr内部类中previous()方法并返回其返回值。

    public void remove()

    功能:删除迭代器上次操作指向结点。

    过程:调用ListItr内部类中remove()方法。

    其他方法

    private LinkedList<E> superClone()

    功能:调用Object(基类)的clone()方法进行复制操作。

    过程:如果不能克隆则抛出异常,否则用super调用Object的clone方法并返回。

    public Object clone()

    功能:重写Object的clone()方法,用于链表的复制。

    过程:调用superClone()方法进行一次浅复制,然后把这个复制的链表对象置空,遍历原链表,然后进行复制,最后返回。

    public Object[] toArray()

    功能:把链表的元素以Object数组的形式返回。

    过程:建立一个大小为size的Object数组,遍历链表把每个结点的元素值赋值给Object数组,最后返回该数组。

    public <T> T[] toArray(T[] a)

    功能:返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组;返回数组的运行时类型为指定数组的类型。如果指定数组能容纳列表,则在其中返回该列表。否则,分配具有指定数组的运行时类型和此列表大小的新数组。

    如果指定数组能容纳列表,并有剩余空间(即数组比列表元素多),则紧跟在列表末尾的数组元素会被设置为 null。(只有 在调用者知道列表不包含任何 null 元素时,才可使用此方法来确定列表的长度。)

    private void writeObject(java.io.ObjectOutputStream s)

    private void readObject(java.io.ObjectInputStream s)

    暂时不明确该方法功能及过程。

    public Spliterator<E> spliterator()

    功能:返回一个Spliterator迭代器。

    过程:返回一个LLSpliterator<E>的实例。

    内部类 static final class LLSpliterator<E> implements Spliterator<E>

    暂时不明确用法及功能。

  • 相关阅读:
    CodeForces 288A Polo the Penguin and Strings (水题)
    CodeForces 289B Polo the Penguin and Matrix (数学,中位数)
    CodeForces 289A Polo the Penguin and Segments (水题)
    CodeForces 540C Ice Cave (BFS)
    网站后台模板
    雅图CAD
    mbps
    WCF学习-协议绑定
    数据库建表经验总结
    资源位置
  • 原文地址:https://www.cnblogs.com/Wayne-T/p/4368296.html
Copyright © 2011-2022 走看看