2016-03-02 26 views
3

在遍歷該集合時將元素添加到可修改的SortedSet安全嗎?特別是,將元素添加到集合中的後續元素比迭代器指示的元素更安全嗎?在迭代時向SortedSet添加元素是否安全

例如,將下面的代碼破壞SortedSet s或拋出一個異常(這將可能是一個ConcurrentModificationException):

/** 
    * s not null, is modifiable. 
    */ 
private final addSelectedFollowers(final SortedSet<Integer> s) 
{ 
    for (Integer i: s) { 
     if (shouldAddNext(i)) { 
      s.add(i + 1); 
     } 
    } 
} 

protected abstract boolean shouldAddNext(int i); 

我的猜測是,它安全的,但我不能在JRE API文檔中找到明確的聲明。我知道如果行爲沒有被指定,實現可以自由決定行爲。在SortedSet的文件中缺乏明確的說明是不夠的,回答這個問題的方式或其他;所需的行爲可能會間接指定,在不同的類或接口的文檔中。不幸的是,JRE文檔並不總是明確說明允許的內容。因此,我正在尋找參考JRE API的答案,而不是光頭斷言。我也知道SortedSet可以做成unmodifiable,這會使SortedSet.add()失敗;我對可修改的SortedSet感興趣。

請注意,我問的是添加元素的集合,而不是modifying elements within the set

+0

取決於'SortedSet'的實現。只需選擇已知的子類,「ConcurrentSkipListSet」不會; 'TreeSet'會。 –

+0

@AndyTurner @fabian實現'interface'的程序員實現一個'interface'必須符合他/她使用的所有'interface'和'classes'的合約(規範)。所以它*不依賴於實現,*如果合約(規範)指示只能通過具有我感興趣的屬性的實現來滿足。我的問題的實質是找到JRE規範的一部分這表明'SortedSet'具有該屬性,或者顯示實現可能無法獲得該屬性並且符合JRE規範。 – Raedwald

+1

@Rededwald,如果接口沒有指定行爲,那麼決定他們想要做什麼取決於實現。 –

回答

4

如果未指定行爲,則實現可以自由決定行爲。

例如,如已知的實現類在Javadoc列出的兩個類實現兩個行爲:

  • ConcurrentSkipListSet

    迭代器是反映組的狀態弱一致,返回元件在創建迭代器時或之後的某個時刻。 他們不會拋出ConcurrentModificationException異常,並可能與其他操作同時進行。

  • TreeSet

    此類的iterator方法返回的迭代器是快速失敗的:如果集合隨時修改創建迭代器之後,以任何方式,除了通過迭代器自己刪除方法,迭代器將拋出ConcurrentModificationException異常

然而,更根本的是,Collection.add(和Set.add)記錄爲可選操作,所以我們可以永遠依靠調用SortedSet.add是安全的,無論是在範圍內正在進行的迭代或不。

例如,呼籲通過Collections.unmodifiableSortedSet返回的SortedSetaddGuava ImmutableSortedSet將導致UnsupportedOperationException

+0

「'Collection.add(和Set.add)'被記錄爲可選操作」,是的。當然,我對一個可修改的已排序集[已編輯的問題進行說明]隱含地感興趣。 – Raedwald

+0

@Raedwald你怎麼知道它是否是一個可修改的'SortedSet'? –

+0

對於公共或受保護的上下文(方法),您可以要求在您的API文檔中對其進行修改。對於'private'上下文(方法)或本地上下文(局部變量),您可以控制所有內容。 – Raedwald

5

這取決於實施。例如,在TreeSet的情況下,迭代器是快速故障,因此在迭代過程中添加元素將觸發ConcurrentModificationException

TreeSet的JavaDoc:

此類的iterator方法返回的迭代器是快速失敗的:如果集合隨時修改後的迭代器創建的,以任何方式,除了通過迭代器自己的remove方法,迭代器將拋出ConcurrentModificationException。因此,面對併發修改,迭代器快速而乾淨地失敗,而不是在將來某個未確定的時間冒着任意的,非確定性的行爲風險。

其他使用非故障快速迭代器的實現可能允許在迭代時添加元素。

相關問題