ArrayList迭代器实现

我们可以看到,通过实现iterator()这个方法,返回了一个Iterator的对象

public Iterator<E> iterator() {
        return new Itr();
  }

Itr是一个内部类,实现了Iterator接口,在这里面实现了hasNext(),next(),remove(),forEachRemaining()方法,

返回的便是由该类生成的对象

 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;

        // prevent creating a synthetic constructor
        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];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        @Override
        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i < size) {
                final Object[] es = elementData;
                if (i >= es.length)
                    throw new ConcurrentModificationException();
                for (; i < size && modCount == expectedModCount; i++)
                    action.accept(elementAt(es, i));
                // update once at end to reduce heap write traffic
                cursor = i;
                lastRet = i - 1;
                checkForComodification();
            }
        }

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

最后的checkForComodification方法,其实是用来检查在迭代过程中有无被修改,如果被修改的话抛出ConcurrentModificationException异常,避免了混乱。

next,remove方法中我们也可以看出不能还没有操作next方法便使用remove方法,便会抛出异常illegalStatementException,原因就是如果还没有使用next方法,lastEct=-1,而remove方法中当lastect<0时,便会抛出异常,同理也可得知,当remove一个元素后,lastEct便会变为-1,再次使用remove也会抛出异常。

public class Main {

    public static void main(String[] args) {
	// write your code here
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("the");
        arrayList.add("first");
        arrayList.add("test");
        arrayList.add("second");
        Iterator itr = arrayList.iterator();
        itr.remove();
    }
}

  

ArrayList除了实现Iterator,还实现了ListIterator迭代器

ListIterator继承了Itr,就是上面那个内部类,还实现了ListIterator接口,而ListIterator接口又继承了Iterator接口,

所以ListIterator有Iterator的所有方法。

private class ListItr extends Itr implements ListIterator<E>

listiterator增添的新方法

在这其中,listiterator新添的一个add方法,我们可以看到,如果多次使用add方法,所添加的元素将会一次被放到当前游标元素之前,这些元素在添加的过程就还是有序加入集合中,并且是放在previous和next这两个游标之间。每一次添加游标都会向右移一位。

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();
            }
        }

这里用到的是ArrayList.add(int index,Element e)方法。

 public void add(int index, E element) {
        rangeCheckForAdd(index);
        modCount++;
        final int s;
        Object[] elementData;
        if ((s = size) == (elementData = this.elementData).length)
            elementData = grow();
        System.arraycopy(elementData, index,
                         elementData, index + 1,
                         s - index);
        elementData[index] = element;
        size = s + 1;
    }

总结:迭代器的使用将访问逻辑与数据结构分离开来,不同的数据结构都可以用同样的逻辑来读取这些数据。

在collection继承的Iterable接口,则所有的集合都将会实现迭代器。

Iterator是基本的迭代器,实现了hasnext()、next()、remove()几个方法,其中需要注意的是如果没有先使用next()方法,便使用remove()方法,将会抛出illegalStateException异常。而且也不可连续使用remove方法,不然同样会抛出异常。

ListIterator是在Iterator的基础上增添了一些方法,其中的add方法可以将一些元素有序的添加到某个元素之前,即next游标所在元素的前方,按加入顺序进行排列

猜你喜欢

转载自blog.csdn.net/chenjiazhanxiao/article/details/84255181