listIterator迭代器的学习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HBL6016/article/details/81060802

在看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可以定位当前索引位置。

那么接下来我们来看一下源码:

        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的话就在开头添加。

 

 

阅读更多
换一批

没有更多推荐了,返回首页