JAVA集合:迭代器实现原理

前言

在JAVA的学习和开发中,经常需要对集合或者数组进行遍历,遍历的方法有多种:for循环、foreach、迭代器。
for循环的实现简单明了,就是循环下标,判断边界,取到每个下标的数据。至于foreach和迭代器,其实foreach在反编译以后可以看到就是迭代器实现的,因此,今天来学习一下迭代器的实现原理。

Iterable 与 Iterator

Iterable:

//Iterable用来标识可以迭代
public interface Iterable<T> {
	//只有一个返回迭代器的方法
    Iterator<T> iterator();
}

//集合的父接口Collection继承自Iterable,所以List和Set都有返回迭代去的方法
public interface Collection<E> extends Iterable<E> {
}

Iterator:
迭代器接口

public interface Iterator<E> {
   //判断边界,是否还有下一个对象,即是否还能迭代
    boolean hasNext();
   //返回下一个对象
    E next();
   //移除当前指针指向的对象
    void remove();
}

迭代器的使用流程是:
1、通过hasNext判断边界,是否可以继续迭代
2、通过next() 方法返回指针指向的对象
3、remove()方法移除指针指向的对象,remove之前必须先执行过next()

迭代器在不同的集合里有不同的实现。
下面来看下各种集合的迭代器实现,主要理解原理。

ArrayList

//迭代器
private class Itr implements Iterator<E> {
//游标
       int cursor = 0;
       
        int lastRet = -1;
	//记录修改次数,每次修改+1
        int expectedModCount = modCount;
	
	//是否还有下一条数据,只需判断游标是否不等于size() ,
        public boolean hasNext() {
            return cursor != size();
        }
	
	//取到这个游标的数据
        public E next() {
            checkForComodification();
            try {
                int i = cursor;
                E next = get(i);
                lastRet = i;
                cursor = i + 1;
                return next;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }
	
	//在迭代器中移除
        public void remove() {
        //一次迭代 不能remove多次
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.remove(lastRet);
                if (lastRet < cursor)
                    cursor--;
                lastRet = -1;
                //更新expectedModCount为最新
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }
	
	//在迭代器之外修改数据就会报错
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

//实现从后往前遍历
private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            cursor = index;
        }

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

        public E previous() {
            checkForComodification();
            try {
                int i = cursor - 1;
                E previous = get(i);
                lastRet = cursor = i;
                return previous;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

        public int nextIndex() {
            return cursor;
        }

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

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

            try {
                AbstractList.this.set(lastRet, e);
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

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

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

LinkedList

 private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned = null;
        private Node<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;

        ListItr(int index) {
            // assert isPositionIndex(index);
            next = (index == size) ? null : node(index);
            nextIndex = index;
        }
	//判断下一个index<size说明有下一条
        public boolean hasNext() {
            return nextIndex < size;
        }

        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();
	    
            lastReturned = next;
            next = next.next;
            //索引+1
            nextIndex++;
            //返回数据
            return lastReturned.item;
        }

        public boolean hasPrevious() {
            return nextIndex > 0;
        }

        public E previous() {
            checkForComodification();
            if (!hasPrevious())
                throw new NoSuchElementException();

            lastReturned = next = (next == null) ? last : next.prev;
            nextIndex--;
            return lastReturned.item;
        }

        public int nextIndex() {
            return nextIndex;
        }

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

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

        public void set(E e) {
            if (lastReturned == null)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.item = e;
        }

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

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

其他的都差不多,就不贴源码了,理解原理最重要。

猜你喜欢

转载自blog.csdn.net/qq_28605513/article/details/84981036