出现异常代码如下
for (Iterator<PromotionChannelShopPo> iterator = channelShopPoList.iterator(); iterator.hasNext(); ) {
PromotionChannelShopPo promotionChannelShopPo = iterator.next();
String channelCode = promotionChannelShopPo.getChannel();
String storeCode = promotionChannelShopPo.getStoreCode();
if (!processChannels.contains(channelCode)) {
logger.info("促销规则ID [{}], 不支持处理渠道 [{}}", ruleId, channelCode);
iterator.remove();
}
if (!storeCodes.contains(storeCode)) {
logger.info("促销规则ID [{}], 不支持处理门店 [{}}", ruleId, storeCode);
iterator.remove();
}
}
抛出java.lang.IllegalStateException异常代码出现在第二个iterator.remove();
我们知道使用增强for循环删除list后继续遍历会抛出 ConcurrentModificationException
按理说使用迭代器删除是不会出现异常的啊,对伐
不过既然出现,我们看下迭代器的remove方法,它是怎么抛出IllegalStateException 不就知道原因了嘛
首先 Iterator 是一个接口,所以我们看迭代的对象ArrayList,
所以,我们应该查看的对象是 ArrayList.Itr.remove 方法
// index of next element to return
int cursor;
// index of last element returned; -1 if no such
int lastRet = -1;
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;
// 赋值 lastRet 属性
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
// 抛出异常
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
// 重置 lastRet 属性
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
很明显 ,当lastRet < 0 会抛出 IllegalStateException。
而属性lastRet默认值为-1,只有当调用next方法,会把当前游标cursor赋值到lastRet。
同时删除会重置lastRet为-1。
结论,使用迭代器删除元素:
1、必须调用过一次next方法,才能调用remove方法。
2、调用remove方法后,不能再次删除同一元素。