2016-06-10 47 views
0

我實現一個Iterator它利用另一個Iterator,它的我不知道,它是否支持remove()方法還是不行。Java異常Iterator的合同刪除

考慮下面的邊緣情況:底層迭代器支持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

+0

這兩個例外都是在寫得很好的應用程序中永遠不會發生的,所以在實踐中我看不到這個問題。 – biziclop

+0

授予,但作爲一個完美主義者,它會*使我感到厭煩,'remove()'改變它的異常。我相信它應該總是拋出一個'UnsupportedOperationException',如果底層的Iterator不支持它 - 我只是不知道如何實現這個... – triangular

+0

那麼,在這種情況下,我會說你應該記住你是否已經拋出了一個ISE,並且繼續扔掉它以用於剩餘的物體的壽命。我知道這不是你想要的,但它是一致的。 – biziclop

回答

2

每您鏈接到文件,這兩種例外情況是可以接受的對於remove方法,以及在next之前呼叫remove的情況被明確提及,並且允許投擲IllegalStateException

對於不支持remove,總是拋出UnsupportedOperationException迭代器是一樣扔在非法狀態的IllegalStateExceptionremovenext之前,第二removenext),只拋出其他異常的有效狀態(第一爲有效在next之後的remove)。這兩種例外均適用於處於無效狀態的呼叫 - 因爲狀態無效且操作不受支持。

你的包裹迭代器的工作原理恰到好處 - 它檢查無效狀態,然後委託給一個內部迭代器,然後可能會引發其支持的操作異常。您的迭代器不需要知道內部迭代器是否支持remove,因爲如上所述,在非法狀態下,這兩個異常都是有效的響應。

+0

這也是我的理由 - 我只是不喜歡「remove」的例外情況,但我想我必須忍受它。 – triangular