【菜鸟记坑篇】Iterator遍历时,二次遍历或遍历完成后Iterator转List报空指针异常/或转换无值的情况
作者:互联网
继上一篇文章后又报新问题,废话不多说上代码!
Iterator it = null;
//说明我们有要除去这些有的
if (oldPO.size() > 0) {
for (it = userListVO.iterator(); it.hasNext(); ) {
OauthUserVO userVO = (OauthUserVO) it.next();
for (int i = 0; i < oldPO.size(); i++) {
if (oldPO.get(i).getPhone().equals(userVO.getPhone())) {
returnFalsList.add(userVO);
it.remove();
continue;
}
}
}
}
userListVO = IteratorUtils.toList(it);//这里转换后并没有值空的只有数组[]
//以下时各种转list的方式
// userListVO = (List<OauthUserVO>) CollectionUtils.collect(myIterator, TransformerUtils.nopTransformer());
// ArrayList<OauthUserVO> elements = Lists.newArrayList(myIterator);
查找了好多相关资料终于捋清楚了。迭代器类似与指针一样的东西。他只是模拟了指针的一些功能,贴源码;
public Iterator<E> iterator() {
return new Itr();
}
// ---------------------------------------------------我是分割线-------------------------------------------------------------------
private class Itr implements Iterator<E> {
/**
* 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 {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)
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();
}
}
通过源码可以看出
int cursor; //当前索引
int lastRet = -1; //前一位索引
int expectedModCount = modCount; //Iterator 修改次数 = collection修改次数
hasNext() //返回 cursor != size()
next() //获取cursor指向的对象,并lastRet=cursor++
remove() //移除lastRet指向的对象,并cursor--
checkForComodification() //判断集合的修改次数是否合法
当Collection调用iterator方法后,根据当前Collection对象,返回一个新的Iterator,
hasNext():
返回 cursor!=size()结果;
checkForComodification():
判断 modCount!=expectedModCount ,为true则抛出ConcurrentModificationException();
next():
调用Collection.get(cursor),返回cursor值指向的索引的元素,并lastRet=cursor,cursor++(这里就是第二次遍历无法进行的原因,
当Iterator遍历完成,cursor == Collection.size(),调用hasNext()时返回false);
上述解释是摘抄另外一篇博客
我理解的上述意思就是当我们在使用next()方法时指针会向下指一位当你遍历完成之后指针指向最后一位,这时你在调用hasnext()方法时就会返回false ,而我们最初创建时迭代器指向的时上一位元素指向一个空值
终于找到了原因。好了原因找到了。只要想办法把指向重置回去就可以了。奈何java没有自带自能自己写重置。对于我来说这个有点难,如果有大神可以写出来希望能发我一份嘿嘿!!
不过话说回来我这里的问题已经解决因为我完全没必要再转一次
本来我一位删除的是Iterator里的数据没想到他删除的也是list里面的数据。终于结束了!
感谢下面博主
https://blog.csdn.net/weixin_40163047/article/details/79303751
标签:遍历,Iterator,int,菜鸟,lastRet,next,cursor,checkForComodification 来源: https://blog.csdn.net/AlanZhoujun/article/details/97933161