這篇文章來(lái)自我的博客
正文之前
在前面兩篇文章中已經(jīng)講述了 LinkedList 基于列表和基于隊(duì)列的操作,這一篇文章作為 LinkedList 系列文章的最后一篇艺智,將會(huì)講述迭代器的用法:
- ListItr
- DescendingIterator
正文
1. ListItr
- 成員變量
- 構(gòu)造
- 增
- 刪
- 改
- 查
在源碼中,ListItr 對(duì)象是私有的菇用,對(duì)象的發(fā)布是通過(guò) listIterator() 方法進(jìn)行的杰刽,關(guān)于對(duì)象的發(fā)布這里不講述,先看看 listIterator() 方法是怎樣的:
//index是從1開(kāi)始的
public ListIterator<E> listIterator(int index) {
//先檢查給出的索引是否有效
checkPositionIndex(index);
//返回 ListItr 對(duì)象
return new ListItr(index);
}
然后看看 ListItr 類:
private class ListItr implements ListIterator<E> {}
1. 成員變量
//當(dāng)前節(jié)點(diǎn)
private Node<E> lastReturned;
//下一個(gè)節(jié)點(diǎn)
private Node<E> next;
//下一個(gè)節(jié)點(diǎn)的位置
private int nextIndex;
private int expectedModCount = modCount;
2. 構(gòu)造
ListItr(int index) {
// assert isPositionIndex(index);
//需要判斷索引是否有效蔫缸,然后確定下一個(gè)節(jié)點(diǎn)
next = (index == size) ? null : node(index);
//下一個(gè)節(jié)點(diǎn)的位置
nextIndex = index;
}
傳入的參數(shù) index 是從1開(kāi)始的腿准,一試便知:
3. 增
方法中使用到了之前寫(xiě)的基于列表的操作:
public void add(E e) {
checkForComodification();
lastReturned = null;
//最后一個(gè)節(jié)點(diǎn)
if (next == null)
//末尾添加
linkLast(e);
else
//在指定位置添加
linkBefore(e, next);
//把下一個(gè)節(jié)點(diǎn)的位置往后移
nextIndex++;
expectedModCount++;
}
4. 刪
方法中使用到了之前寫(xiě)的基于列表的操作:
public void remove() {
checkForComodification();
//如果當(dāng)前節(jié)點(diǎn)為空
if (lastReturned == null)
throw new IllegalStateException();
//定義一個(gè)節(jié)點(diǎn),表示當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
Node<E> lastNext = lastReturned.next;
//刪除節(jié)點(diǎn)
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
//將當(dāng)前節(jié)點(diǎn)設(shè)為null
lastReturned = null;
expectedModCount++;
}
5. 改
將當(dāng)前節(jié)點(diǎn)中的元素改為傳入的參數(shù):
public void set(E e) {
//如果節(jié)點(diǎn)為空
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}
6. 查
迭代器支持雙向操作拾碌,所以能夠向前或向后移動(dòng):
向后移動(dòng):
//判斷是否有下一個(gè)節(jié)點(diǎn)
public boolean hasNext() {
return nextIndex < size;
}
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
//將下一個(gè)節(jié)點(diǎn)表示為當(dāng)前節(jié)點(diǎn)
lastReturned = next;
next = next.next;
//位置向后移動(dòng)
nextIndex++;
//返回當(dāng)前節(jié)點(diǎn)的元素
return lastReturned.item;
}
//返回下一個(gè)節(jié)點(diǎn)的位置
public int nextIndex() {
return nextIndex;
}
向前移動(dòng)吐葱,操作是類似的:
public boolean hasPrevious() {
return nextIndex > 0;
}
public E previous() {
checkForComodification();
if (!hasPrevious())
throw new NoSuchElementException();
//向前移,并修改位置
lastReturned = next = (next == null) ? last : next.prev;
nextIndex--;
//返回元素
return lastReturned.item;
}
//同樣是返回位置
public int previousIndex() {
return nextIndex - 1;
}
2. DescendingIterator
反向迭代器對(duì)象的發(fā)布方式也和上面的一樣校翔,通過(guò) descendingIterator() 來(lái)發(fā)布對(duì)象:
public Iterator<E> descendingIterator() {
return new DescendingIterator();
}
private class DescendingIterator implements Iterator<E> {}
反向迭代器實(shí)現(xiàn)的方法就3個(gè)弟跑,我們先看一眼成員變量:
private final ListItr itr = new ListItr(size());
其實(shí)反向迭代器是基于 ListItr 來(lái)實(shí)現(xiàn)的,直接在迭代器的初始位置設(shè)置在鏈表的末尾
接下來(lái)來(lái)看看3個(gè)方法:
public boolean hasNext() {
return itr.hasPrevious();
}
public E next() {
return itr.previous();
}
public void remove() {
itr.remove();
}
因?yàn)檫@是反向的展融,所以向前方法的名字還是 next()窖认,但是,是使用了 previous 來(lái)進(jìn)行的
那么告希,有關(guān) LinkedList 的基本用法的源碼就已經(jīng)解讀完畢了扑浸,接下來(lái)會(huì)是其他容器類的源碼解讀