Iterator的Java异常合同删除

时间:2016-06-10 21:50:59

标签: java exception collections

我实现了一个Iterator,它利用了另一个Iterator,我不知道它是否支持remove()方法。

考虑以下边缘情况:底层迭代器支持remove()并且我的Iterator next()尚未被调用。

我是否违反了界面合约,如果我remove()抛出 - 在这种情况下 - IllegalStateException而不是UnsupportedOperationException? (只要调用next(),就可以调用基础remove(),这将抛出相应的UnsupportedOperationException。)

如果是这样,我怎么能重构我的代码来检查底层Iterator是否支持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;
        }
    };
}

(出于我们的目的,我们可以假设传递的Collection不包含null。)

1 个答案:

答案 0 :(得分:2)

根据您链接到的文档,remove方法都可以接受这两个例外,并明确提到remove之前调用next的情况,并允许抛出{{ 1}}。

对于不支持IllegalStateException的迭代器,始终抛出remove与将UnsupportedOperationException置于非法状态(IllegalStateException remove之前一样有效。 },next之后的第二个remove,并且仅将其他异常抛出到有效状态(next之后的第一个remove)。这两个例外都适用于处于无效状态的调用 - 因为状态无效且操作不受支持。

你的包装迭代器工作正常 - 它检查无效状态,然后委托给内部迭代器,然后可能抛出不支持的操作异常。您的迭代器不需要知道内部迭代器是否支持删除,因为如上所述,在非法状态下,两个异常都是有效响应。