arraylist的迭代器的实现研究---其中的iterator(不是listiterator)---(源码)

总结:
1.什么next,hasnext—-其实不是next,是当前容器内元素数组的指针指向的元素,其实是当前
2.必须在next()后使用remove()【因为只有next()会改变lastret】,
总之用remove()之前必须要有next(),并且不能连续remove();remove()—只能
—-几个next();—–直接没有remove–;remove();—-几个next();—–直接没有remove–;remove();
3.这只是arraylist的迭代器研究,其他容器的迭代器的实现是不同的,具体要看源码
4.迭代器就是创建了一个类似指针的对象(就是有些指针功能的对象),指向当前的容器中元素组的当前元素。(绕口),
并且基本功能会实现下遍历方法,尼玛如果要求太多就累赘了。

Iterator接口源码
public interface Iterator {
boolean hasNext();
E next();
void remove();
}

看容器类图可以看清
ListIterator继承Iterator接口
list接口有方法生成ListIterator接口(即list接口的实现类有方法返回一个ListIterator接口的实现类的对象的引用,这个实现类的对象的引用估计向上转型成ListIterator)
collection接口有方法生成listiterator接口。

下面来具体分析下如何实现的。
在arraylist中
public Iterator iterator() {
return new Itr();
}

然后发现这个Itr()是个内部类的对象,这个内部类实现了Iterator(如下图)
private class Itr implements Iterator {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;//size是arrylist的属性,表示这个容器的size,你看这个内部类的                        从不减1,就知道,这个就相当c++数组中的a[i]的i了。所以i最大是size-1,
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification(); //就是个检查,和本文主体无关
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();//比如一个size是8,i只能0-7
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();//说实话,不清楚这个为什么还要判断一次。因为elementData.length必定>=size的啊。。。。。我记得看严蔚敏数据结构曾经看到过,以前也记得,反正先放这,复习数据结构的时候再看。
        cursor = i + 1;
        return (E) elementData[lastRet = i];//其实是返回当前对象-------哎不知道为什么用next()这个误导的词语
    }

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

        try {
            ArrayList.this.remove(lastRet);//这个调用了arraylist中的remove,其实是同一个功能,就是移除某个序列号,只不过这个序列号正好永远是容器元素指针当前指向的那个元素。但是一开始的时候,这个lastret是-1,而且每次remove之后都会再次给他-1,所以必须在next()后使用remove()【因为只有next()会改变lastret】,

总之用remove()之前必须要有next(),并且不能连续remove();remove()—只能
—-几个next();—–直接没有remove–;remove();—-几个next();—–直接没有remove–;remove();

            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

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

对于remove的验证,请看测试代码
package test1;
import java.util.*;
public class test3 {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Integer[] fuck =  {new Integer(2),new Integer(3),new Integer(4),new Integer(5)};
    ArrayList<Integer> guan = new ArrayList<Integer>();
    for(int i = 0; i < fuck.length;i++)
    {   
        guan.add(fuck[i]);
        System.out.println(fuck[i]);
    }   
    Iterator<Integer> shu = guan.iterator();
//  shu.remove();
    System.out.println("remove one");
    Integer gg = shu.next();
    shu.remove();
    System.out.println("remove two");
//  shu.remove();
    System.out.println("remove three");
    Integer hh = shu.next();
    shu.remove();
    System.out.println("remove four");
    System.out.println(gg.intValue());
    System.out.println(hh.intValue());

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值