LinkedHashSet作为API公共方法的返回类型

3

让我们考虑以下示例。

编写一个API,其中包含返回唯一对象集合的公共方法。我认为将该方法的返回类型设置为Set可以向用户展示其具有唯一性。如果这些项目是唯一且有序的,则将返回类型设置为LinkedHashSet是否正确,或者将其设置为Collection更好?

我知道一些既唯一又排序的集合。我想知道将公共方法的返回类型类(TreeSet、SortedSet、LinkedHashSet)设置为何种类型才是一个好主意。从面向对象编程的角度来看。


排序还是有序?如果需要有序,最好使用List - Tom Hawtin - tackline
因为我无法想象为什么它很重要,所以很难回答,但另一种选择是返回一个Set,并在javadoc中写明它是有序的。调用者通常不会关心,对吧?这是相同的接口。 - Fredrik
7个回答

8
您可以返回SortedSet - 这意味着项目已排序且唯一。
您还可以使用SetUniqueList(来自commons-collection)并返回List(在javadoc中指示元素是唯一的),或者任何集合并返回Set(并在javadoc中指示有序属性)。 LinkedHashSet 保留插入顺序,但由于您的对象可能正在进行插入,因此对客户端没有任何意义。

感谢SetUniqueList,它是一个不错的类型,但它并没有回答我的问题。 - narek.gevorgyan
这只是一个建议。其他的回答了你的问题——LinkedHashSet 对客户端来说没有任何意义。 - Bozho

5
如果您的项目是独特的,那么我会返回一个Set。然后在方法的Javadoc中说明这些项目保证按排序顺序排列。

嗯,其实我更喜欢@Bozho的回答! - Perception
+1。我认为你的答案比Bozho的好得多,因为它实际上回答了问题。;-) - ruakh

5
我建议不要返回LinkedHashSet(除非你有非常好的理由)。如果你返回Set,你可以根据需要更改Set的实现,例如HashSetTreeSet等。
在这种情况下,我认为你建议返回Set是一个好主意,因为它确实表明了项目是唯一的。这也表明contains通常会很快(O(1)或O(log n))。
另一方面,Collection非常通用,但它告诉调用者的只是一组普通的东西,没有任何关于排序或唯一性的特殊约束。指定Set意味着不存在关于唯一性的混淆,并且你可以在任何可以使用Collection的地方使用它。

2
回答您的问题,您应该问自己:“这个方法返回的最通用类型是什么?”

如果该方法的特征是返回一些唯一的对象,并以某种方式进行排序,则代表此类的最通用标准类是SortedSet

如果您返回一个TreeSet,那么该方法将提供有关其返回内容实现的详细信息(即, TreeSet是一个具体类,而不是接口),这通常是面向对象编程中要避免的。

如果您返回一个Collection,则您并未说明对象是唯一的,也没有说明它们按某种方式排序。

如果您返回一个LinkedHashSet,不仅未说明返回的集合以某种方式排序,而且在面向对象编程的抽象方面也存在问题(这是一个具体类,因此泄露了实现细节;除非有充分理由,否则始终尝试返回接口)。


1

如果一个方法的返回值是一个具有一致排序的Set<...>,并且这是该方法的契约的一部分,那么我只会给它一个返回类型为LinkedHashSet<...>。即使如此,除非该方法的返回值是可修改的,否则我也会对此持谨慎态度,因为LinkedHashSet<...>也排除了使用Collections.unmodifiableSet(...)的可能性。

在大多数情况下,我认为Set<...>是更好的返回类型。或者,如果一致的排序特别重要,那么您可以使用SortedSet<...>并切换到其中一个实现(例如TreeSet<...>);这仍然允许使用Collections.unmodifiableSortedSet(...)


0
如果你想明确它们是唯一的,并且仅基于插入顺序排序,那么你可以返回 LinkedHashSet。然而,Set 通常是更好的选择。

0
从即将发布的Java 21开始,您可以返回一个SequencedSet。这将表示结果既是一个具有唯一元素的Set,又是一个具有明确定义的遇到顺序的SequencedCollection
这样做的额外好处是使用接口而不是具体类来定义方法签名。例如,通过不声明返回的具体实现类型,可以为将来对方法进行更改以返回更合理的集合类型提供灵活性,同时仍然保证它是一个具有明确定义排序的Set

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接