我正在实现一个迭代器,它利用另一个迭代器,我不知道它是否支持remove()
方法。
考虑以下边缘情况:底层迭代器不支持remove()
,并且对于我的迭代器next()
尚未调用。
如果我的remove()
在这种情况下抛出IllegalStateException
而不是UnsupportedOperationException
,我是否违反了接口合约?
(一旦调用next()
,就可以调用底层remove()
,这将引发相应的UnsupportedOperationException
。
如果是这样,我如何重构我的代码以检查底层迭代器是否支持 remove()
?
举个例子:
<T> Iterator<T> getSetViewIterator(Collection<T> collection) {
Iterator<T> uniqueItr = new HashSet<>(collection).iterator();
return new Iterator<T>() {
private T current = null;
private boolean hasRemoved = true;
@Override
public boolean hasNext() {
return uniqueItr.hasNext();
}
@Override
public T next() {
if(!hasNext())
throw new NoSuchElementException();
hasRemoved = false;
return current = uniqueItr.next();
}
@Override
public void remove() {
if(hasRemoved)
throw new IllegalStateException();
for(Iterator<T> iterator = collection.iterator(); iterator.hasNext();) {
if(iterator.next().equals(current))
iterator.remove();
}
hasRemoved = true;
}
};
}
(出于我们的目的,我们可以假设传递的集合不包含null
。
根据您链接到的文档,这两种例外对于 remove
方法都是可以接受的,并且明确提到了在 next
之前调用 remove
的情况,并允许抛出IllegalStateException
。
对于不支持remove
的迭代器,总是抛出UnsupportedOperationException
与将IllegalStateException
抛入非法状态(remove
在next
之前,第二个remove
在next
之后)一样有效,并且只在有效状态下抛出另一个异常(第一个remove
在next
之后)。这两种例外都适用于处于无效状态的调用 - 因为状态无效且操作不受支持。
您的包装迭代器工作得很好 - 它检查无效状态,然后委托给内部迭代器,然后可能会引发其不受支持的操作异常。迭代器不需要知道内部迭代器是否支持 remove ,因为如上所述,在非法状态下,这两个异常都是有效的响应。