ListIterator的LinkedList实现

源码来自jdk1.8


对于实现了List接口的集合类,他们的iterator都是通过实现ListIterator接口得到的,每个集合类都有自己的ListIterator实现,这里给出LinkedList的实现:

private class ListItr implements ListIterator<E> {
    private Node<E> lastReturned;
    private Node<E> next;
    private int nextIndex;
    private int expectedModCount = modCount;
    //省略了方法
}

lastReturned和next说明了迭代器一直处于元素之间的位置,lastReturned代表了上次访问过的元素,next表示下一个要访问的元素,由于可以向前迭代,所以这两个可以是同一个节点。

hasNext / next

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

        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();

            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }

通过节点的next域在链表中迭代

remove

每次删除lastReturned节点,然后lastReturned置空,所以不能连续两次调用remove函数。

    public void remove() {
        checkForComodification();
        if (lastReturned == null)
            throw new IllegalStateException();
        Node<E> lastNext = lastReturned.next;
        unlink(lastReturned);
        if (next == lastReturned)
            next = lastNext;
        else
            nextIndex--;
        lastReturned = null;
        expectedModCount++;
    }

set与remove类似,修改lastReturned。

checkForComodification

如果迭代器发现它的集合被另一个迭代器或是集合自身的方法修改(添加/删除元素)了,抛出一个ConcurrentModificationException(fast-fail快速失败)。实现方法是集合与迭代器分别维护一个独立的集合改写次数,每个迭代器方法开始的地方都检查数值是否一致,迭代器自身的修改方法会增加自己以及集合的修改次数,而集合本身的方法只会增加集合的修改次数。

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

这个特性在使用foreach(内部使用iterator实现)时也会触发,例如

foreach(element e: list){
    if(condition){
        list.remove(e);
    }
};

所以需要使用iterator自己的remove来对容器进行修改:

Iterator<Element> e = list.iterator();  
while(e.hasNext()){  
    Element element = e.next();
    if(condition){
        e.remove();
    }
}

add

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

通过迭代器添加节点

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一.线性表 定义:零个或者多个元素的有限序列。也就是说它得满足以下几个条件:  ①该序列的数据元素是有限的。  ②...
    Geeks_Liu阅读 2,714评论 1 12
  • 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:V...
    独念白阅读 813评论 0 2
  • Java源码研究之容器(1) 如何看源码 很多时候我们看源码, 看完了以后经常也没啥收获, 有些地方看得懂, 有些...
    骆驼骑士阅读 1,009评论 0 22
  • 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:V...
    Oneisall_81a5阅读 908评论 0 11
  • 随着社交网络平台的普遍化,人与人之间的交往越来越多地依赖微信,微博,QQ,无论是大事小事急事闲事,都喜欢用微信来...
    卡茉阅读 430评论 3 1