Iterator和ListIterator理解

我在学习Iterator时的一个误区:当使用Iterator()或ListIterator()方法生成迭代器对象时,迭代器对象指向第一个元素。

1、事实上,当使用Iterator()或ListIterator()方法生成迭代器对象时,迭代器对象不指向任何元素。
Iterator接口的部分实现如下:

    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return 下一个元素的下标
        int lastRet = -1; // index of last element returned; -1 if no such 这个才是当前迭代器指向的元素的下标
        int expectedModCount = modCount;

        Itr() {}

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
    }

当使用Iterator()方法生成一个迭代器对象时,当前下标lastRet = -1;因此此时迭代器不指向任何元素,因此,如果在调用next()之前执行remove(),是不合法的操作。

2、我在查ListIterator()的说明文档时,有这样一段说明文字:它的游标位置总是位于previous()返回的元素和调用next()的元素之间。
在这里插入图片描述
我对这个模型不是很理解,因为参照Iterator(),cursor应该是指向元素的,为什么会位于元素之间,所以再去查看代码,结果发现类ListItr继承自类Itr,即类Itr的数据域cursor和lastRetcursor在ListIterator()中也是存在的,且hasNext()、next()这两个方法都没有重写:

private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            super();
            cursor = index;
        }

        public boolean hasPrevious() {
            return cursor != 0;
        }

        public int nextIndex() {
            return cursor;
        }

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

        @SuppressWarnings("unchecked")
        public E previous() {
            checkForComodification();
            int i = cursor - 1;
            if (i < 0)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i;
            return (E) elementData[lastRet = i];
        }
    }

所以,ListIterator的结构和Iterator的结构是差不多的;
它的游标位置总是位于previous()返回的元素和调用next()的元素之间。这句话大概是为了方便对previous()和next这些方法的理解。
事实上,next()返回的是下标为cursor的元素,这一项是和Iterator保持一致的,pervious()返回的是下标为lastRet的元素,即下标为cursor-1的元素(当前元素)。
下面是一个例子:
在调用next()函数之前就调用previousIndex()和nextIndex()方法;
调用next()函数之前,lastRet=-1,cursor=0
因此第一行输出为-1 0

	public static void main(String[] args) {
		ArrayList<String> str = new ArrayList<String>();
		for (int i = 0; i < 10; i++) {
			str.add("string"+i);
		}
		
		ListIterator<String> it = str.listIterator();
		while(it.hasNext()) {
		    //这里在调用next()函数之前就调用previousIndex()和nextIndex()方法;
		    //调用next()函数之前,lastRet=-1,cursor=0
		    //因此第一行输出为-1 0
			System.out.println(it.previousIndex()+"  "+it.nextIndex());
			it.next();	
		}
		System.out.println(it.previousIndex()+"  "+it.nextIndex());
		System.out.println(str);

	}
	
	/*Output
	*-1  0
    *0  1
    *1  2
    *2  3
    *3  4
    *4  5
    *5  6
    *6  7
    *7  8
    *8  9
    *9 10
	*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值