迭代器删除的 Java 异常合约



我正在实现一个迭代器,它利用另一个迭代器,我不知道它是否支持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抛入非法状态(removenext之前,第二个removenext之后)一样有效,并且只在有效状态下抛出另一个异常(第一个removenext之后)。这两种例外都适用于处于无效状态的调用 - 因为状态无效且操作不受支持。

您的包装迭代器工作得很好 - 它检查无效状态,然后委托给内部迭代器,然后可能会引发其不受支持的操作异常。迭代器不需要知道内部迭代器是否支持 remove ,因为如上所述,在非法状态下,这两个异常都是有效的响应。

相关内容

最新更新