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 ? get(i)==null : 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 ? get(i)==null : 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 ? get(i)==null : 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。