本文共 2611 字,大约阅读时间需要 8 分钟。
实现ArrayList迭代器的方法,目前只实现了普通迭代器的方法
所有分析随代码附上/** * 调用内部类MItr * @return */ @Override public MyIteratoriterator() { return new MItr(); } /** * 内部类MItr * 实现MyIterator接口的所有迭代器方法 */ private class MItr implements MyIterator { int cursor; //迭代器的游标,表示下一个元素的索引位置 int prev=-1; //表示上一个元素的索引位置 int exceptModCount=modCount; //该迭代器职责内预期执行修改的次数 //exceptModCount的初值为modCount @Override public boolean hasNext() { return cursor!=size; //当下个元素游标没有走到elements最后一个元素上时返回true //当前迭代的位置不是数组的最大容量值就返回true } @Override public E next() { //检查是否有来自不属于该迭代器的修改 checkModificationCount(); //i用于维护cursor与prev的关系 int i=cursor; if(i>=size){ throw new NoSuchElementException("from E next() of MItr"); } //防止其他对象删除元素脱标 //为什么要在check了之后还在这里判断一次? //情况设想: //由集合删除会修改modCount被 checkModificationCount() filter //由其他Iterator删除 不会动modCount,也不应该有权利动 会逃过filter //exceptModCount又是个人独有,互相无法修改,成员内部类也无法有静态变量 Object[] elements = MyArrayList.this.elements; if(i>=elements.length){ throw new ConcurrentModificationException("from "+i+">="+"elements.length:"+elements.length+" of E next() of MItr"); } cursor=i+1; return (E) MyArrayList.this.elements[prev=i]; } @Override public void remove() { //初始时认为是防止没有移动光标而调用remove //用测试用例调试时发现,其实是next方法一次只会让cursor返回一个 E //如果你移除了这个 E,因为cursor会占据prev的位置,那么你就丢失了prev //这时会把prev设成初始状态-1,表示无法找到上一个结点 //从而用这个判断禁止连续移除,因为这会导致后续的previous类操作失效 if(prev<0){ throw new IllegalStateException(); } checkModificationCount(); try { MyArrayList.this.remove(prev); cursor = prev; //???? prev = -1; //同步修改次数 exceptModCount = modCount; } catch (IndexOutOfBoundsException e){ throw new ConcurrentModificationException("from remove() of MItr"); } } /** * 检查是否有来自其他对象的修改 */ private void checkModificationCount() { if(exceptModCount!=MyArrayList.this.modCount){ throw new ConcurrentModificationException("another iterator or collection fixed object!"); } } }
转载地址:http://hxvli.baihongyu.com/