java迭代器源码_java迭代器源码浅析

先贴出测试代码:

public static void main(String[] args) {

List list=new ArrayList();

list.add("aa");

list.add("bb");

list.add("cc");

Iterator iterator =list.iterator();

while(iterator.hasNext()){

String aaString=iterator.next();

if(aaString.equals("aa")){

iterator.remove();

}

}

for (String string : list) {

System.out.println(string);

}

}

运行结果:

bb

cc

我们跟进list.iterator()源码,选择 ArrayList 实现类,发现源码中ArrayList 继承与AbstractList,发现ArrayList实现类中并没有iterator()方法,那么肯定是在父类中,跟进源码发现,iterator()源码如下:

public Iterator iterator() {

return new Itr();

}

发现new 了一个 Itr,跟进继续,发现Itr 实现了Iterator接口,部分源码如下:

private class Itr implements Iterator {

/**

* Index of element to be returned by subsequent call to next.

*/

int cursor = 0;

/**

* Index of element returned by most recent call to next or

* previous. Reset to -1 if this element is deleted by a call

* to remove.

*/

int lastRet = -1;

/**

* The modCount value that the iterator believes that the backing

* List should have. If this expectation is violated, the iterator

* has detected concurrent modification.

*/

int expectedModCount = modCount;

public boolean hasNext() {

return cursor != size();

}

public E next() {

checkForComodification();

try {

E next = get(cursor);

lastRet = cursor++;

return next;

} catch (IndexOutOfBoundsException e) {

checkForComodification();

throw new NoSuchElementException();

}

}

public void remove() {

if (lastRet == -1)

throw new IllegalStateException();

checkForComodification();

try {

AbstractList.this.remove(lastRet);

if (lastRet < cursor)

cursor--;

lastRet = -1;

expectedModCount = modCount;

} catch (IndexOutOfBoundsException e) {

throw new ConcurrentModificationException();

}

}

final void checkForComodification() {

if (modCount != expectedModCount)

throw new ConcurrentModificationException();

}

} private class Itr implements Iterator {

/**

* Index of element to be returned by subsequent call to next.

*/

int cursor = 0;

/**

* Index of element returned by most recent call to next or

* previous. Reset to -1 if this element is deleted by a call

* to remove.

*/

int lastRet = -1;

/**

* The modCount value that the iterator believes that the backing

* List should have. If this expectation is violated, the iterator

* has detected concurrent modification.

*/

int expectedModCount = modCount;

public boolean hasNext() {

return cursor != size();

}

public E next() {

checkForComodification();

try {

E next = get(cursor);

lastRet = cursor++;

return next;

} catch (IndexOutOfBoundsException e) {

checkForComodification();

throw new NoSuchElementException();

}

}

public void remove() {

if (lastRet == -1)

throw new IllegalStateException();

checkForComodification();

try {

AbstractList.this.remove(lastRet);

if (lastRet < cursor)

cursor--;

lastRet = -1;

expectedModCount = modCount;

} catch (IndexOutOfBoundsException e) {

throw new ConcurrentModificationException();

}

}

final void checkForComodification() {

if (modCount != expectedModCount)

throw new ConcurrentModificationException();

}

}

根据源码我们发现Itr()里定义了三个变量:

int cursor = 0;下一个将要返回的元素的索引;

int lastRet = -1;lastRet记录上一次游标所在位置,因此它总是比cursor少1,-1表示最近的一次操作没有返回元素。

int expectedModCount = modCount;

其中的modCount 是AbstractList包含的一个modCount变量,它的初始值是0,当集合每被修改一次时(调用add,remove等方法),modCount加1。因此,modCount如果不变,表示集合内容未被修改。

expectedModCount 初始赋值等于modCount的值,后续会校验两个变量是否相等,如果不等会抛出异常ConcurrentModificationException。

为什么直接使用list.remove()会抛异常,而使用iterator中的remove方法却不报错?关键点在这里:

public void remove() {

if (lastRet == -1)

throw new IllegalStateException();

checkForComodification();

try {

AbstractList.this.remove(lastRet);

if (lastRet < cursor)

cursor--;

lastRet = -1;

expectedModCount = modCount;

} catch (IndexOutOfBoundsException e) {

throw new ConcurrentModificationException();

}

}

final void checkForComodification() {

if (modCount != expectedModCount)

throw new ConcurrentModificationException();

}

分析源码,咱们发现,首先判断本次操作是否有返回元素,如果没有,就抛出异常,然后检查expectedModCount和modCount是否相等,如果不想等就会抛出异常。接下来调用List本身的remove方法,索引指定位lastRet,此时,浮标减少一位,lastRet为-1,表示上次没有返回数据,最后关键一步,同步修改的modCount变量值,这样就保证remove后不抛出异常。

个人研究笔记,不准之处,还请见谅!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值