listIterator迭代器的学习

3 篇文章 0 订阅
2 篇文章 0 订阅

在看listIterator迭代器之前,我们先来总结一下它与iterator迭代器的相同点和不同点。

相同点:

1)都是迭代器,在对集合进行遍历时都可以使用。

2)都有hashNext和next方法,都能顺序遍历。

3)都可以实现删除操作。

说的更直白一点的话,就是iterator有的方法功能,listIterator都包含了,因为它会继承iterator在list的实现类。

那我们就看一下listIterator到底与iterator有什么不同吧。

不同点:

1)listIterator只能用于list集合,而不能用于所有的集合。

2)listIterator可以实现向list中添加元素。

4)listIterator可以实现list修改元素。

5)listIterator可以实现逆序遍历。

6)listIterator可以定位当前索引位置。

那么listIterator多了那些方法?看一下源码:

        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];
        }

这个previous()方法与next()方法相反,它是返回迭代位置之前的元素,那么对应的肯定有一个类似于HashNext()的方法:

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

这个方法就是判断当前指针位置有没有超过第一个指针位置,没有就返回true,有的话就返回false。

这里的cursor是下一个元素的索引,在previous()方法中,i表示的那就是当前的索引,然后重新将值赋给了cursor,取值的时候则是根据i取得当前的元素。这样就实现了逆序遍历的过程。这个过程正好与顺序遍历相反,顺序遍历哪里的cursor = i + 1;

逆序遍历需要先获取最后的指针,就是列表的结尾,写个测试小例子:

	public static void main(String[] args) throws CloneNotSupportedException {
		ArrayList<String> a=new ArrayList<>();
		a.add("1");
		a.add("2");
		a.add("3");
		a.add("4");
		ListIterator<String> b = a.listIterator();
		while(b.hasNext()) {
			System.out.println("顺序遍历:"+b.next());
		}
		for(;b.hasPrevious();) {
			System.out.println("逆序遍历:"+b.previous());
		}
	}

打印结果:

顺序遍历:1
顺序遍历:2
顺序遍历:3
顺序遍历:4
逆序遍历:4
逆序遍历:3
逆序遍历:2
逆序遍历:1

实现了我们想要的打印结果。

接下来我们来看看它的添加方法:

        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                ArrayList.this.add(i, e);
                cursor = i + 1;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

首先它校验了int expectedModCount = modCount;是否是一致的,这就是看看在迭代过程中有没有调用ArrayList中的操作。

然后调用ArrayList的add方法,这里的的方法使得modCount数值加1,这样在最后又进行了一次赋值expectedModCount = modCount;使得在迭代过程中执行此操作时也保持expectedModCount 的数值与modCount相等。cursor = i + 1;是下一个索引数,而首次添加则根据迭代的顺序进行,这里的添加是看cursor 的值进行的如果为0的话就在开头添加。

还有一个特有方法set方法:

        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.set(lastRet, e);
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

从方法中可以看到,ListIterator迭代器中的set传的参数只有元素,没有传指针,而在下面它获取了list中的最后一个指针,调用ArrayList方法中的set(key,value)说明迭代器中的set添加元素是放在list后面的。

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值