3 回答

TA貢獻1942條經驗 獲得超3個贊
由于您的示例使用私有字段,因此隱藏實現類型并不重要。您(或維護此類的任何人)始終可以查看字段的初始值設定項以查看它是什么。
但是,根據它的使用方式,可能值得為該字段聲明一個更具體的接口。將其聲明為 a 表示允許重復,并且排序很重要。將其聲明為 a 表示不允許重復,并且排序并不重要。您甚至可以將字段聲明為具有特定的實現類(如果其中有重要內容)。例如,將其聲明為 “表示不允許重復項,但排序很重要。List
Set
LinkedHashSet
如果類型出現在類的公共 API 中,以及該類的兼容性約束是什么,那么是否使用接口以及使用哪個接口的選擇將變得更加重要。例如,假設有一個方法
public ??? getRegisteredListeners() { return ... }
現在,返回類型的選擇會影響其他類。如果您可以更改所有呼叫者,也許這沒什么大不了的,您只需要編輯其他文件即可。但假設調用方是一個您無法控制的應用程序?,F在,接口的選擇至關重要,因為您無法在不破壞應用程序的情況下更改它。這里的規則通常是選擇最抽象的接口,以支持您希望調用方想要執行的操作。
大多數 Java SE API 返回 。這提供了從底層實現的相當程度的抽象,但它也為調用方提供了一組合理的操作。調用方可以迭代、獲取大小、執行包含檢查或將所有元素復制到另一個集合。Collection
某些代碼庫用作要返回的最抽象的接口。它所做的只是允許調用方進行迭代。有時這是所有必要的,但與 相比,它可能有些限制。Iterable
Collection
另一種選擇是返回 .如果您認為調用方可能希望使用流的操作(如篩選、映射、查找等),而不是迭代或使用集合操作,這將非常有用。Stream
請注意,如果選擇返回 或 ,則需要確保返回不可修改的視圖或創建防御性副本。否則,調用方可能會修改類的內部數據,這可能會導致 bug。(是的,即使是可以修改!請考慮獲取 一個,然后調用該方法。如果返回 ,則無需擔心,因為不能使用 來修改基礎源。Collection
Iterable
Iterable
Iterator
remove()
Stream
Stream
請注意,我將有關字段聲明的問題轉換為有關方法返回類型聲明的問題。有一種“編程到接口”的想法在Java中非常普遍。在我看來,對于局部變量來說,這并不重要(這就是為什么它通??梢允褂茫瑢τ谒接凶侄蝸碚f也無關緊要,因為這些(幾乎)根據定義只影響它們被聲明的類。但是,“程序到接口”原則對于API簽名非常重要,因此在這些情況下,您確實需要考慮接口類型。私人領域,不是那么多。var
(最后一點:有一種情況是,你需要關注私有字段的類型,那就是當你使用一個直接操作私有字段的反射框架時。在這種情況下,您需要將這些字段視為公共字段 - 就像方法返回類型一樣 - 即使它們未聲明。public

TA貢獻1817條經驗 獲得超6個贊
與所有事情一樣,這是一個權衡問題。有兩種對立的力量。
類型越通用,實現的自由度就越高。如果您使用,則可以自由使用 、或,而不會影響用戶/調用方。
Collection
ArrayList
HashSet
LinkedList
返回類型越通用,用戶/調用方可用的功能就越少。提供基于索引的查找。A 使得通過 、 和 獲取連續子集變得容易。A 提供了高效的 O(log n) 二進制搜索查找方法。如果您返回 ,則這些都不可用。只能使用最通用的訪問函數。
List
SortedSet
headSet
tailSet
subSet
NavigableSet
Collection
此外,子類型保證特殊屬性不:s 保存唯一項。已排序。有訂單;它們不是無序的物品袋。如果使用,則用戶/調用方不一定假定這些屬性成立。他們可能被迫進行防御性編碼,例如,即使您知道不會有重復項,也可以處理重復項。Collection
Set
SortedSet
List
Collection
合理的決策過程可能是:
如果 O(1) 索引訪問得到保證,請使用 。
List
如果元素已排序且唯一,請使用 或 。
SortedSet
NavigableSet
如果元素唯一性得到保證,但順序沒有保證,請使用 。
Set
否則,請使用 。
Collection

TA貢獻1784條經驗 獲得超7個贊
這實際上取決于您要對集合對象執行的操作。
Collection<String> cSet = new HashSet<>(); Collection<String> cList = new ArrayList<>();
在這種情況下,如果你愿意,你可以做:
cSet = cList;
但如果你喜歡:
Set<String> cSet = new HashSet<>();
盡管您可以使用構造函數構造新列表,但不允許執行上述操作。
Set<String> set = new HashSet<>(); List<String> list = new ArrayList<>(); list = new ArrayList<>(set);
所以基本上取決于你可以使用的用法或接口。Collection
Set
添加回答
舉報