簡體   English   中英

什么接口表示具有插入順序迭代的LinkedHashSet

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM