源码-LinkedList

LinkedList

1概述

LinkedList,基于节点实现的双向链表,每个节点都有指向前一个节点和后一个节点的数据

2类图

在这里插入图片描述
1.相较于ArrayList,少继承java.util.RandomAccess接口,不支持随机访问
2.java.util.Deque 接口,提供支持双端队列的功能
3.继承java.util.AbstractSequentialList(抽象连续队列),他是AbstractList的子类,实现了只能连续访问的数据存储的get(int index)等随机操作的方法
4.一般情况下,对于支持随机访问的继承AbstractList,不支持的继承AbstractSequentialList抽象类,但是LinkedList选择重写AbstractSequentialList方法

3属性

//双向链表的头节点和尾节点以及节点的数量
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
//静态内部类
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;
    }
}

4构造方法

public LinkedList() {
}

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

public boolean addAll(int index, Collection<? extends E> c) {
    //验证index是否有效
    checkPositionIndex(index);
    //将集合转换为obj数组
    Object[] a = c.toArray();
    //得到集合长度
    int numNew = a.length;
    if (numNew == 0)//如果添加元素为0,返回
        return false;

    Node<E> pred, succ; //获取index位置节点succ与前一个节点pred
    //尾部添加,前一个元素为last
    if (index == size) {
        succ = null;
        pred = last;
    } else {
    //其他index位置添加,succ获取index位置节点,插入元素的prev=succ的前一个节点
    //index元素的prev赋值给pred
        succ = node(index);
        pred = succ.prev;
    }
    //遍历数组添加到pred后面
    for (Object o : a) {
        @SuppressWarnings("unchecked") E e = (E) o;
        //前一个元素,当前元素,下一个元素
        //遍历参数集合,初始化一个node,设置为pred
        Node<E> newNode = new Node<>(pred, e, null);
        //如果前一个元素为null则是首节点
        if (pred == null)
            first = newNode;
        else
        //否则前一个节点的下一个节点为当前节点newNode
            pred.next = newNode;
        //设置pred也就是下一个节点的前一个节点为当前节点
        pred = newNode;
    }
    //修改succ和ored的指向
    //遍历结束之后,succ==null 前一个节点设置为last
    //如果succ为null则是最后一个节点,将前一个节点赋值给尾节点last
    if (succ == null) {
        last = pred;
    } else {
    //将当前index节点赋值为前一个节点的下一个节点,succ的前一个节点赋值为pred
        pred.next = succ;
        succ.prev = pred;
    }
    //设置size
    size += numNew;
    //设置数组改变数
    modCount++;
    return true;
}

private void checkPositionIndex(int index) {
    if (!isPositionIndex(index))
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private boolean isPositionIndex(int index) {
    return index >= 0 && index <= size;
}

5 add(E e)添加单个元素

public boolean add(E e) {
    //添加元素到队尾
    linkLast(e);
    return true;
}
 //添加元素到队尾
void linkLast(E e) {
    //记录原last节点为l
    final Node<E> l = last;
    //创建新节点:前一个节点为last,后一个节点为null
    final Node<E> newNode = new Node<>(l, e, null);
    //将新节点赋值给last
    last = newNode;
    //如果最后一个节点为null说明first为null
    if (l == null)
        //将新节点赋值给first
        first = newNode;
    else
        //否则将l的next赋值为新节点
        l.next = newNode;
    size++;
    modCount++;
}

6 add(int index,E e)指定位置添加单个元素

public void add(int index, E element) {
    checkPositionIndex(index);
    //如果尾部添加
    if (index == size)
        linkLast(element);
    else
        //在index上添加
        linkBefore(element, node(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++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}
//添加元素e到succ节点前面
void linkBefore(E e, Node<E> succ) {
    // assert succ != null;
    //获取succ前一个节点
    final Node<E> pred = succ.prev;
    //创建新节点赋值prev与succ
    final Node<E> newNode = new Node<>(pred, e, succ);
    //设置右移节点的前一个节点
    succ.prev = newNode;
    //如果前一个节点为null,说明添加的节点为first节点
    if (pred == null)
        first = newNode;
    else
    //否则succ前一个节点的next节点为新节点
        pred.next = newNode;
    size++;
    modCount++;
}

7 addFirst(E e)头部添加元素

/**
 * Inserts the specified element at the beginning of this list.
 * 插入指定元素在list开始
 * @param e the element to add
 */
public void addFirst(E e) {
    linkFirst(e);
}
private void linkFirst(E e) {
	//创建一个节点f赋值为first
    final Node<E> f = first;
    //创建一个新节点并放到first之前
    final Node<E> newNode = new Node<>(null, e, f);
    //将新节点赋值给first
    first = newNode;
    //如果头节点为null,说明之前为空list,尾节点指向新节点
    if (f == null)
        last = newNode;
        //否则设置原first的上一个节点为新节点
    else
        f.prev = newNode;
    size++;
    modCount++;
}

如果linked为空:firstlastnull;

如果linked只有一个元素:firstlaste

8 addLast(E e)尾部添加

//调用的是linkLast(E e)上面有写
public void addLast(E e) {
    linkLast(e);
}

9 实现Queue接口,以下方法:

public boolean offer(E e) {
    return add(e);
}
public void push(E e) {
    addFirst(e);
}

10 remove(int index)移除单个元素

/**
 * Removes the element at the specified position in this list.  Shifts any
 * subsequent elements to the left (subtracts one from their indices).
 * 删除指定位置元素,后面所有元素左移,并返回移除的元素
 * Returns the element that was removed from the list.
 *
 * @param index the index of the element to be removed
 * @return the element previously at the specified position
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E remove(int index) {	
    //检查元素位置
    checkElementIndex(index);
    return unlink(node(index));
}
//移除不为null的元素
E unlink(Node<E> x) {
    // assert x != null;
    //获取index位置存储的元素
    final E element = x.item;
    //获取index位置元素的上一个和下一个元素
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;
	//如果当前元素前一个元素为null,说明是为first
    if (prev == null) {
        first = next;
    } else {
    	//指定删除元素前一个元素的next
        prev.next = next;
        //将删除元素的prev指向null
        x.prev = null;
    }

	//同上,对于next元素进行检查,并将x的引用赋值为null,gc回收
    if (next == null) {
        last = prev;
    } else {
        next.prev = prev;
        x.next = null;
    }

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

11 remove(Object o)移除指定元素

/**
 * Removes the first occurrence of the specified element from this list,
 * 删除第一次出现的指定元素
 * if it is present.  If this list does not contain the element, it is
 * unchanged.  More formally, removes the element with the lowest index
 * {@code i} such that
 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
 * (if such an element exists).  Returns {@code true} if this list
 * contained the specified element (or equivalently, if this list
 * changed as a result of the call).
 *
 * @param o element to be removed from this list, if present
 * @return {@code true} if this list contained the specified element
 */
public boolean remove(Object o) {
    if (o == null) {
    //遍历,直到元素x为null,并判断item是否为null
        for (Node<E> x = first; x != null; x = x.next) {
            if (x.item == null) {
            	//删除方法
                unlink(x);
                return true;
            }
        }
    } else {
        for (Node<E> x = first; x != null; x = x.next) {
            if (o.equals(x.item)) {
                unlink(x);
                return true;
            }
        }
    }
    return false;
}

12 删除首个元素和删除最后一次出现的元素

public boolean removeFirstOccurrence(Object o) {
    return remove(o);
}
public boolean removeLastOccurrence(Object o) {
    if (o == null) {
        for (Node<E> x = last; x != null; x = x.prev) {
            if (x.item == null) {
                unlink(x);
                return true;
            }
        }
    } else {
        for (Node<E> x = last; x != null; x = x.prev) {
            if (o.equals(x.item)) {
                unlink(x);
                return true;
            }
        }
    }
    return false;
}

13remove() 删除首个元素

 /**
 * Retrieves and removes the head (first element) of this list.
 * 检索并删除list的头,也就是第一个元素
 * @return the head of this list
 * @throws NoSuchElementException if this list is empty
 * @since 1.5
 */
public E remove() {
    return removeFirst();
}
public E removeFirst() {
     //获取first节点
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}
//删除非null的第一个元素
private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
    //获取first的item
    final E element = f.item;
    //创建next节点指向first的next
    final Node<E> next = f.next;
    //将原first的item设置为null
    f.item = null;
    f.next = null; // help GC
    //first指向next
    first = next;
    //之前只有一个元素,已删除,全部为null
    if (next == null)
        last = null;
    else
    	//将新的first节点prev指向null
        next.prev = null;
    size--;
    modCount++;
    return element;
}

14 removeLast()删除最后一个元素

/**
 * Removes and returns the last element from this list.
 * 删除并返回最后一个元素
 * @return the last element from this list
 * @throws NoSuchElementException if this list is empty
 */
public E removeLast() {
    final Node<E> l = last;
    if (l == null)
        throw new NoSuchElementException();
    return unlinkLast(l);
}
//删除最后一个元素
private E unlinkLast(Node<E> l) {
    // assert l == last && l != null;
    //获取最后一个元素item对象
    final E element = l.item;
    //获取最后一个元素的prev
    final Node<E> prev = l.prev;
    //将item设置为null
    l.item = null;
    l.prev = null; // help GC
    //将前一个而元素设置为last
    last = prev;
    //如果前一个为null说明最后一个元素已经被删除
    if (prev == null)
        first = null;
    else
        prev.next = null;
    size--;
    modCount++;
    return element;
}

15poll() pop()…

/**
 * Retrieves and removes the head (first element) of this list.
 * 检索和删除头
 * @return the head of this list, or {@code null} if this list is empty
 * @since 1.5
 */
public E poll() {
    final Node<E> f = first;
    return (f == null) ? null : unlinkFirst(f);
}
/**
 * Retrieves and removes the first element of this list,
 * or returns {@code null} if this list is empty.
 * 删除list第一个元素,为空时返回null
 * @return the first element of this list, or {@code null} if
 *     this list is empty
 * @since 1.6
 */
public E pollFirst() {
    final Node<E> f = first;
    return (f == null) ? null : unlinkFirst(f);
}

/**检索和删除最后一个元素或者返回null
 * Retrieves and removes the last element of this list,
 * or returns {@code null} if this list is empty.
 *
 * @return the last element of this list, or {@code null} if
 *     this list is empty
 * @since 1.6
 */
public E pollLast() {
    final Node<E> l = last;
    return (l == null) ? null : unlinkLast(l);
}
 /** 
 * Pops an element from the stack represented by this list.  In other
 * words, removes and returns the first element of this list.
 * 弹出一个元素
 * <p>This method is equivalent to {@link #removeFirst()}.
 *
 * @return the element at the front of this list (which is the top
 *         of the stack represented by this list)
 * @throws NoSuchElementException if this list is empty
 * @since 1.6
 */
 public E pop() {
    return removeFirst();
}

16 removeAll(Collection<?> c)/AbstractCollextion

 /**
 * {@inheritDoc}
 *
 * <p>This implementation iterates over this collection, checking each
 * element returned by the iterator in turn to see if it's contained
 * in the specified collection.  If it's so contained, it's removed from
 * this collection with the iterator's <tt>remove</tt> method.
 *
 * <p>Note that this implementation will throw an
 * <tt>UnsupportedOperationException</tt> if the iterator returned by the
 * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
 * and this collection contains one or more elements in common with the
 * specified collection.
 *
 * @throws UnsupportedOperationException {@inheritDoc}
 * @throws ClassCastException            {@inheritDoc}
 * @throws NullPointerException          {@inheritDoc}
 *
 * @see #remove(Object)
 * @see #contains(Object)
 */
public boolean removeAll(Collection<?> c) {
    Objects.requireNonNull(c);
    boolean modified = false;
    Iterator<?> it = iterator();
    while (it.hasNext()) {
        if (c.contains(it.next())) {
            it.remove();
            modified = true;
        }
    }
    return modified;
}
ArrayList重写了整个方法,迭代器没有使用数组性能号

17retainAll(Collection<?> c)交集

public boolean retainAll(Collection<?> c) {
    Objects.requireNonNull(c);
    boolean modified = false;
    Iterator<E> it = iterator();
    while (it.hasNext()) {
        if (!c.contains(it.next())) {
            it.remove();
            modified = true;
        }
    }
    return modified;
}

18 indexOf(Object o) 查找单个元素位置

/**
 * Returns the index of the first occurrence of the specified element
 * in this list, or -1 if this list does not contain the element.
 * More formally, returns the lowest index {@code i} such that
 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
 * or -1 if there is no such index.
 *
 * @param o element to search for
 * @return the index of the first occurrence of the specified element in
 *         this list, or -1 if this list does not contain the element
 */
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;
}

contains(Object o)就是基于此方法实现的

19 lastIndexOf(Object o)最后一个指定元素的位置

/**
 * Returns the index of the last occurrence of the specified element
 * in this list, or -1 if this list does not contain the element.
 * 返回最后一次出现的指定元素位置,返回-1表示不存在
 * More formally, returns the highest index {@code i} such that
 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
 * or -1 if there is no such index.
 *
 * @param o element to search for
 * @return the index of the last occurrence of the specified element in
 *         this list, or -1 if this list does not contain the element
 * 反向遍历获取index
 */
public int lastIndexOf(Object o) {
    int index = size;
    if (o == null) {
        for (Node<E> x = last; x != null; x = x.prev) {
            index--;
            if (x.item == null)
                return index;
        }
    } else {
        for (Node<E> x = last; x != null; x = x.prev) {
            index--;
            if (o.equals(x.item))
                return index;
        }
    }
    return -1;
}

20 get(int index) 获取指定位置元素

/**
 * Returns the element at the specified position in this list.
 * 返回指定位置元素
 * @param index index of the element to return
 * @return the element at the specified position in this list
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E get(int index) {
    checkElementIndex(index);
    return node(index).item;
}
//实现deque接口会实现相关方法
public E peek() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
}
 public E peekFirst() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
 }
 public E peekLast() {
    final Node<E> l = last;
    return (l == null) ? null : l.item;
}
public E getFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return f.item;
}
public E getLast() {
    final Node<E> l = last;
    if (l == null)
        throw new NoSuchElementException();
    return l.item;
}
区别就是:deque实现的方法当list为null时返回null,linkedList方法抛出异常

21 set(int index, E element) 设置元素到指定位置

/**
 * Replaces the element at the specified position in this list with the
 * specified element.
 *
 * @param index index of the element to replace
 * @param element element to be stored at the specified position
 * @return the element previously at the specified position
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E set(int index, E element) {
    checkElementIndex(index);
    Node<E> x = node(index);
    E oldVal = x.item;
    x.item = element;
    return oldVal;
}

22 toArray()转换为数组

 /**
 * Returns an array containing all of the elements in this list
 * in proper sequence (from first to last element).
 * 返回数组包含list所有元素(顺序)
 * <p>The returned array will be "safe" in that no references to it are
 * maintained by this list.  (In other words, this method must allocate
 * a new array).  The caller is thus free to modify the returned array.
 *  返回的数组将是“安全的”,因为此列表不维护对它的引用。(换句话说,这个方法必须分配一个新数组)。
 * 因此,调用者可以自由地修改返回的数组。
 * <p>This method acts as bridge between array-based and collection-based
 * APIs.
 *
 * @return an array containing all of the elements in this list
 *         in proper sequence
 */
public Object[] toArray() {
	//创建obj数组,设置size
    Object[] result = new Object[size];
    int i = 0;
    //遍历链表
    for (Node<E> x = first; x != null; x = x.next)
        result[i++] = x.item;
    return result;
}
/**
 * Returns an array containing all of the elements in this list in
 * proper sequence (from first to last element);
 *  the runtime type ofthe returned array is that of the specified array.  If the list fits
 * in the specified array, it is returned therein.  Otherwise, a new
 * array is allocated with the runtime type of the specified array and
 * the size of this list.
 * 返回的数组的运行时类型是指定数组的运行时类型。如果列表符合指定的数组,
 * 则返回该列表。否则,将使用指定数组的运行时类型和此列表的大小分配新数组。
 * <p>If the list fits in the specified array with room to spare (i.e.,
 * the array has more elements than the list), the element in the array
 * immediately following the end of the list is set to {@code null}.
 * (This is useful in determining the length of the list <i>only</i> if
 * the caller knows that the list does not contain any null elements.)
 *
 * <p>Like the {@link #toArray()} method, this method acts as bridge between
 * array-based and collection-based APIs.  Further, this method allows
 * precise control over the runtime type of the output array, and may,
 * under certain circumstances, be used to save allocation costs.
 *
 * <p>Suppose {@code x} is a list known to contain only strings.
 * The following code can be used to dump the list into a newly
 * allocated array of {@code String}:
 *
 * <pre>
 *     String[] y = x.toArray(new String[0]);</pre>
 *
 * Note that {@code toArray(new Object[0])} is identical in function to
 * {@code toArray()}.
 *
 * @param a the array into which the elements of the list are to
 *          be stored, if it is big enough; otherwise, a new array of the
 *          same runtime type is allocated for this purpose.
 * @return an array containing the elements of the list
 * @throws ArrayStoreException if the runtime type of the specified array
 *         is not a supertype of the runtime type of every element in
 *         this list
 * @throws NullPointerException if the specified array is null
 */
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
 	//如果返回的数组a的length小于size,则会新建一个数组T[]
    if (a.length < size)
        a = (T[])java.lang.reflect.Array.newInstance(
                            a.getClass().getComponentType(), size);
    int i = 0;
    //将T[]转换为Obje[]
    Object[] result = a;
    for (Node<E> x = first; x != null; x = x.next)
    	//Obj[]填入list元素
        result[i++] = x.item;
	//如果指定T[]length大于size则增加一个分界线size的位置null
    if (a.length > size)
        a[size] = null;

    return a;
}

23 hashCode与equals

AbstractList中的hashCode与equals,与ArrayList一样都是使用父类方法

24 clear()清空链表

/**
 * Removes all of the elements from this list.
 * The list will be empty after this call returns.
 */
public void clear() {
    // Clearing all of the links between nodes is "unnecessary", but:
    // - helps a generational GC if the discarded nodes inhabit
    //   more than one generation
    // - is sure to free memory even if there is a reachable Iterator
    //遍历链表并将他们的元素,前后元素都设置为null
    for (Node<E> x = first; x != null; ) {
    	//先将next存入临时变量,以便修改遍历条件
        Node<E> next = x.next;
        x.item = null;
        x.next = null;
        x.prev = null;
        x = next;
    }
    first = last = null;
    size = 0;
    modCount++;
}

25 writeObject(java.io.ObjectOutputStream s)序列化

/**
 * Saves the state of this {@code LinkedList} instance to a stream
 * (that is, serializes it).
 *
 * @serialData The size of the list (the number of elements it
 *             contains) is emitted (int), followed by all of its
 *             elements (each an Object) in the proper order.
 */
private void writeObject(java.io.ObjectOutputStream s)
    throws java.io.IOException {
    // Write out any hidden serialization magic
    //默认写出非静态非transient
    s.defaultWriteObject();
	//写出size
    // Write out size
    s.writeInt(size);
	//写出node中的元素
    // Write out all elements in the proper order.
    for (Node<E> x = first; x != null; x = x.next)
        s.writeObject(x.item);
}
反序列化也是如此;

26 clone() 克隆

public Object clone() {
    //克隆基本属性和string
    LinkedList<E> clone = superClone();
	
    // Put clone into "virgin" state
    //设置first和last
    clone.first = clone.last = null;
    clone.size = 0;
    clone.modCount = 0;

    // Initialize clone with our elements
    //初始化克隆方法的元素
    for (Node<E> x = first; x != null; x = x.next)
        clone.add(x.item);

    return clone;
}

27 subList(int fromIndex, int toIndex)创建子链表

/**
 * {@inheritDoc}
 *
 * <p>This implementation returns a list that subclasses
 * {@code AbstractList}.  The subclass stores, in private fields, the
 * offset of the subList within the backing list, the size of the subList
 * (which can change over its lifetime), and the expected
 * {@code modCount} value of the backing list.  There are two variants
 * of the subclass, one of which implements {@code RandomAccess}.
 * If this list implements {@code RandomAccess} the returned list will
 * be an instance of the subclass that implements {@code RandomAccess}.
 *
 * <p>The subclass's {@code set(int, E)}, {@code get(int)},
 * {@code add(int, E)}, {@code remove(int)}, {@code addAll(int,
 * Collection)} and {@code removeRange(int, int)} methods all
 * delegate to the corresponding methods on the backing abstract list,
 * after bounds-checking the index and adjusting for the offset.  The
 * {@code addAll(Collection c)} method merely returns {@code addAll(size,
 * c)}.
 *
 * <p>The {@code listIterator(int)} method returns a "wrapper object"
 * over a list iterator on the backing list, which is created with the
 * corresponding method on the backing list.  The {@code iterator} method
 * merely returns {@code listIterator()}, and the {@code size} method
 * merely returns the subclass's {@code size} field.
 *
 * <p>All methods first check to see if the actual {@code modCount} of
 * the backing list is equal to its expected value, and throw a
 * {@code ConcurrentModificationException} if it is not.
 *
 * @throws IndexOutOfBoundsException if an endpoint index value is out of range
 *         {@code (fromIndex < 0 || toIndex > size)}
 * @throws IllegalArgumentException if the endpoint indices are out of order
 *         {@code (fromIndex > toIndex)}
 */
public List<E> subList(int fromIndex, int toIndex) {
    return (this instanceof RandomAccess ?
            new RandomAccessSubList<>(this, fromIndex, toIndex) :
            new SubList<>(this, fromIndex, toIndex));
}
//类似ArrayList限制指针,**但是ArrayList重写了该方法**
//但是LinkedList使用了AbstractList的subList方法
class SubList<E> extends AbstractList<E> {
private final AbstractList<E> l;
private final int offset;
private int size;

SubList(AbstractList<E> list, int fromIndex, int toIndex) {
    if (fromIndex < 0)
        throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
    if (toIndex > list.size())
        throw new IndexOutOfBoundsException("toIndex = " + toIndex);
    if (fromIndex > toIndex)
        throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                           ") > toIndex(" + toIndex + ")");
    l = list;
    offset = fromIndex;
    size = toIndex - fromIndex;
    this.modCount = l.modCount;
}
**//深入在再研究**
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
    super(list, fromIndex, toIndex);
}

28 iterator()/AbstractSequentialList实现

public Iterator<E> iterator() {
    return listIterator();
}
==》AbstractList
public ListIterator<E> listIterator() {
    return listIterator(0);
}
==》AbstractSequentialList
public abstract ListIterator<E> listIterator(int index);

AbstractSequentialList对AbstractList的 listIterator(int index)方法进行重写,并且在LinkedList对其进行了具体的实现

29 listIterator(int index)获取ListIterator

/**
 * Returns a list-iterator of the elements in this list (in proper
 * sequence), starting at the specified position in the list.
 * Obeys the general contract of {@code List.listIterator(int)}.<p>
 *
 * The list-iterator is <i>fail-fast</i>: if the list is structurally
 * modified at any time after the Iterator is created, in any way except
 * through the list-iterator's own {@code remove} or {@code add}
 * methods, the list-iterator will throw a
 * {@code ConcurrentModificationException}.  Thus, in the face of
 * concurrent modification, the iterator fails quickly and cleanly, rather
 * than risking arbitrary, non-deterministic behavior at an undetermined
 * time in the future.
 *
 * @param index index of the first element to be returned from the
 *              list-iterator (by a call to {@code next})
 * @return a ListIterator of the elements in this list (in proper
 *         sequence), starting at the specified position in the list
 * @throws IndexOutOfBoundsException {@inheritDoc}
 * @see List#listIterator(int)
 */
public ListIterator<E> listIterator(int index) {
    checkPositionIndex(index);
    //创建ListItr迭代器
    return new ListItr(index);
}

private class ListItr implements ListIterator<E> {
	//最后返回的节点
    private Node<E> lastReturned;
    //下一个节点
    private Node<E> next;
    //下一个index位置,从零开始
    private int nextIndex;
    //创建迭代器时数组修改次数
    private int expectedModCount = modCount;
		
	//初始化就是0和first元素
    ListItr(int index) {
        // assert isPositionIndex(index);
        //获取下一个节点
        next = (index == size) ? null : node(index);
        //下一个节点的位置
        nextIndex = index;
    }

    public boolean hasNext() {
        return nextIndex < size;
    }

    public E next() {
        checkForComodification();
        if (!hasNext())
            throw new NoSuchElementException();
		//lastReturned指向,最后访问的节点
        lastReturned = next;
        //指针下移
        next = next.next;
        //index增加
        nextIndex++;
        //返回当前元素信息
        return lastReturned.item;
    }

    public boolean hasPrevious() {
        return nextIndex > 0;
    }

	//前一个元素
    public E previous() {
        checkForComodification();
        if (!hasPrevious())
            throw new NoSuchElementException();
		**//i.next为当前获取元素,last为上一个元素**
		//此时next和lastReturn相等
        lastReturned = next = (next == null) ? last : next.prev;
        nextIndex--;
        return lastReturned.item;
    }

    public int nextIndex() {
        return nextIndex;
    }

    public int previousIndex() {
        return nextIndex - 1;
    }

    public void remove() {
        checkForComodification();
        //如果返回值为null则抛出异常
        if (lastReturned == null)
            throw new IllegalStateException();
		//获取lastReturned下一个节点,也就是next节点
        Node<E> lastNext = lastReturned.next;
        //删除lastReturned节点
        unlink(lastReturned);
        //说明调用previous方法,netxIndex不用变化
        if (next == lastReturned)
            next = lastNext;
        else
        //nextINdex-1
            nextIndex--;
            //设置lastReturn为null
        lastReturned = null;
        expectedModCount++;
    }

    public void set(E e) {
        if (lastReturned == null)
            throw new IllegalStateException();
        checkForComodification();
        lastReturned.item = e;
    }

    public void add(E e) {
        checkForComodification();
        lastReturned = null;
        if (next == null)
            linkLast(e);
        else
            linkBefore(e, next);
        nextIndex++;
        expectedModCount++;
    }

    public void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (modCount == expectedModCount && nextIndex < size) {
            action.accept(next.item);
            lastReturned = next;
            next = next.next;
            nextIndex++;
        }
        checkForComodification();
    }

    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}

previous

  List<String> linked = new LinkedList<>();
    linked.add("1");
    linked.add("2");
    linked.add("3");
    ListIterator<String> iterator = linked.listIterator(1);
    while(iterator.hasNext()){
        System.out.println(iterator.next());
        System.out.println(iterator.previous());
    }
	输出结果都是2
	由此可见,previous只是把索引指向前一个item,返回的仍然是当前的item;而next是真的
	返回下一个item。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值