Java 集合 LinkedList ListIterator
java 迭代器 Iterator 指向两个元素之间的位置
1. 总览:LinkedList 的内部类 ListItr 所实现的 ListIterator接口
public interface ListIterator<E> extends Iterator<E> {
boolean hasNext(); //判断是否存在下一个 Node
E next(); //返回下一个 Node 的值
boolean hasPrevious(); //判断是否存在上一个 Node
E previous(); //返回上一个 Node 的值
int nextIndex(); //返回下一次调用 next 方法时所返回元素的整数索引
int previousIndex(); //返回下一次调用 next 方法时所返回元素的整数索引
/*
* 移除迭代器的 lastReturned 所指向的 Node (即迭代器左侧所指 Node)
* expectedModCount++, 同时调用 unlink() 方法( unlink(lastReturned) 移除 Node )使 modCount++, 保证 expectedModeCount == modeCount
*/
void remove();
void set(E e);
/*
* 在迭代器的 next 所指向的 Node 前,添加一个新的 Node
* expectedModCount++, 同时调用 linkLast(e) 或 linkBefore(e, next) 方法添加节点 Node 并使 modCount++, 保证 expectedModeCount == modeCount
*/
void add(E e);
}
2. remove 方法的具体实现
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
Node<E> lastNext = lastReturned.next;
//调用 LinkedList 的 unlink() 方法移除节点,同时 modeCount++
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
3. add 方法的具体实现
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
//如果迭代器在链表尾部,那么就在尾部添加节点 Node, 同时 modeCount++
linkLast(e);
else
//一般情况就在迭代器的 next 所指向的节点前添加,同时 modeCount++
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
通俗地来讲,LinkedList 的 add 和 remove 方法是直接在链表末尾添加节点 Node;
而 LinkedList 的内部类 ListIter 所实现的 add 和 remove 方法则是在迭代器 Iterator 所在位置来添加和删除节点 Node 的。
4. LinkedList 的使用
package pers.xuelei.learningJava.collection;
import java.util.LinkedList;
import java.util.ListIterator;
public class MyLinkedList {
public static void main(String[] args){
var staff = new LinkedList<String>();
staff.add("Amy");
staff.add("Bob");
staff.add("Carl");
ListIterator<String> staffItr = staff.listIterator();
System.out.println("LinkedList Add Test: ");
while( staffItr.hasNext() ){
if( staffItr.next().equals("Carl") )
staffItr.add("Doom");
}
for( String e : staff ){
System.out.println(e);
}
System.out.println("\n");
/*
* 一定要注意迭代器 Iterator 的位置,像这里 staffItr 的位置目前是在链表的尾部,
* 因此想要再重新遍历链表,要么重新获取一个新的迭代器,要么使用 pervious() 方法 反向遍历
*/
ListIterator<String> staffItr2 = staff.listIterator();
System.out.println("LinkedList Remove Test: ");
while( staffItr2.hasNext() ){
if( staffItr2.next().equals("Bob") )
staffItr2.remove();
}
for( String e : staff ){
System.out.println(e);
}
}
}
/*
输出结果:
LinkedList Add Test:
Amy
Bob
Carl
Doom
LinkedList Remove Test:
Amy
Carl
Doom
*/