[英]What interface represents a LinkedHashSet with insertion order iteration
由於以下代碼行,我被Sonar拉了起來:
public void setFileNames(LinkedHashSet<String> fileNames) {
帶有錯誤消息:
避免使用像'LinkedHashSet'這樣的實現類型; 改為使用界面
當我想表示一個保持其插入順序的非排序Set
,有什么方法呢? 我只是使用Set
並明確表示將保留迭代順序嗎?
存儲的數據將使用JaxB序列化,反序列化后迭代順序必不可少。
(我知道並完全理解這一點 )
沒有這樣的interface
因為輸入需要這種行為是沒有意義的。 創建 Set
代碼可能有關於訂單的意圖,並在創建Set
時選擇適當的實現。
但是,如果Set
具有插入順序,字母順序或任意(例如基於散列的)順序的問題怎么能對setFileNames(Set<String> fileNames)
呢?
將參數類型聲明為Set
可以保證不存在對行為有影響的重復項,但是插入順序是關於Set
的歷史記錄的無意義信息(除非調用者有意義)。
如果你堅持使用方法簽名setFileNames(LinkedHashSet<String> fileNames)
,我仍然可以使用無意義的順序傳入一個Set
,例如調用
setFileNames(new LinkedHashSet<String>(hashSet))
或具有詞典順序的集合,例如setFileNames(new LinkedHashSet<String>(treeSet))
。 你的簽名使它變得更加復雜。
我很欣賞其他答案,我也很欣賞聲納警告。 但是,有時候(或許在您的情況下)可以忽略警告。 在我看來,您正在使用LinkedHashSet
來精確定義調用者的職責。 Set不會傳達您的要求(訂單未保留)。 也沒有List(不保證不同的元素)。 所以也許可以忽略這個警告。
另一種方法是允許List,然后你必須仔細檢查(在你的方法中)列表沒有重復,如果有的話就拋出異常。 這對我來說似乎很荒謬。
正如其他人所說,你應該弄清楚如何抑制聲納中的警告。 希望該機制能夠包含您壓制它的原因。 然后,您可以向未來的維護者解釋您的決定。
只需接受一個Set
,讓調用者決定要傳入的實現。
它保持其插入順序?
這取決於來電者。 LinkedHashSet
在插入時保留順序, TreeSet
根據自然順序保留順序。 為什么您的方法需要關注訂單的實現方式?
如果您需要訂購要接收的元素,那么您的方法應該接收List而不是Set。 但是為了擺脫警告,你必須使用Set而不是LinkedHashSet。 在您的方法中使用接口而不是實際類是一種好習慣。 您不應該公開接口的實際實現。
此外,如果你只需要迭代Set的元素,你就可以收到一個迭代器,然后迭代它。
編輯:如果你真的想確保你只收到一個LinkedHashSet,你可以這樣做:
public void setFileNames(Set<String> fileNames) {
if (!(fileNames instanceof LinkedHashSet)) {
throw new IllegalArgumentException("I need a LinkedHashSet!");
}
}
編輯2:我不認為這里有一個理想的答案,但是如果你確實需要上面所有東西都收到一個LinkedHashSet,我會在界面中聲明它並找到一種方法讓Sonar忽略該警告的特定實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.