java Iterator迭代器详细解释理解

迭代器实际上是对集合的一种循环遍历,是官方对集合的一种遍历方法的封装,

Iterator接口定义了四个方法

 

boolean hasNext();
E next();
default void remove() {
        throw new UnsupportedOperationException("remove");
    }
default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }

 

我以下面这个例子对迭代器的原理做一个解释

public void b(){
        List<String> list = new ArrayList<String>();
        list.add("第一个元素");
        list.add("第二个元素");
        list.add("第三个元素");
        list.add("第四个元素");
        Iterator<String> iterable = list.iterator();
        while (iterable.hasNext()){
            System.out.println(iterable.next());
        }
    }

这个迭代器是对list集合做一个循环,并打印出每一个元素的内容

list.iterator();返回一个Itr类型的对象,Itr是ArrayList类内部的一个类,它实现了Iterator接口所定义的方法

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

当使用hasNext()方法时,实际上它返回的是一个Boolean值,方法中cursor中的初始值是0,size是集合的长度,到这里就应该明白了实际上循环是由这里控制的。

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

那么这个size和cursor的值是怎么来的呢?实际上cursor是Itr类中定义的一个int类型的变量,他没有赋初始值,但是Java默认int类型的变量值为0,每进行进行一次循环的时候cursor的值是在next()方法中

进行+1,(这个地方会在后面的源码中能看到)

size是ArrayLIst中定义的一个Int类型的变量,他的值是怎么来的呢?看到我上面举得这个例子了吗?调用集合的add的方法添加元素,每次进行添加元素的时候,都会加一,看到下面代码标红的地方吗?

这就是每次进行添加元素时size的值都会加一。

 

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

这里有一个注意的地方就是 ensureCapacityInternal(size + 1);这一步是判断当集合首次添加元素的时候会为elementData赋初始长度10

这个10也是ArrayList定义的一个常量

 

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

 

调用Next()方法时返回下一个元素的值,先来看源码,从代码中可以看到这个方法实际上返回的是数组的值,通过数组下标来返回值,另外cursor的值是通过这个方法来进行每次循环+1的

这个lasfRet就是数组下表,

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

那么数组elementData又是怎么来的呢,实际上ArrayList类就是对数组的维护,当创建ArrayList对象的时候自动调用无参构造函数此时无参构造函数

会执行下面这段代码

public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

同时ArrayList类中定义了几个常量和变量

private static final int DEFAULT_CAPACITY = 10;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;

此时elementData代表的是 DEFAULTCAPACITY_EMPTY_ELEMENTDATA这个空常量数组,当进行添加元素的时候调用add()方法此时相当于是对elementData数组添加元素

看到应该都一目了然了把,知道集合其实就是对数组的一种维护

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

新手一个,如有错误请评论指出谢谢

 

posted @ 2022-06-22 09:42  白菜豆腐粉丝汤  阅读(184)  评论(0)    收藏  举报