为什么 LinkedHashSet 没有 addFirst 方法?



正如LinkedHashSet的文档所述,它是

Set接口的哈希表和链表实现可预测的迭代顺序。此实现与HashSet不同因为它维护了一个双链接列表,该列表贯穿其所有条目。

所以它本质上是一个HashSet,具有由链表实现的键的FIFO队列。考虑到LinkedListDeque,并且特别允许在开始时插入,我想知道为什么除了Set接口中存在的方法之外,LinkedHashSet没有addFirst(E e)方法。实现这一点似乎并不难。

正如Eliott Frisch所说,答案在你引用的段落的下一句话中:

…这个链表定义了迭代顺序,即顺序其中元素被插入到集合中(插入顺序(…

addFirst方法会破坏插入顺序,从而破坏LinkedHashSet的设计思想。

如果我也可以添加一些猜测,其他可能的原因可能包括:

  • 实现起来并不像看上去那么简单,因为LinkedHashSet实际上是作为LinkedHasMap实现的,其中没有使用映射到的值。至少您也必须更改该类(这反过来也会破坏插入顺序,从而破坏其设计思想(
  • 正如另一个人可能在评论中所想的那样,他们觉得这没用

也就是说,你问错了问题。他们设计了一个具有他们认为需要的功能的类。他们继续使用哈希表和链表来实现它。您从实现开始,并将其作为设计讨论的基础。虽然这可能偶尔会增加一些有用的东西,但通常这不是好设计的方法。

虽然理论上我可以理解你的观点,即在某种情况下,你可能想要一个具有set属性的双端队列(重复项被忽略/消除(,但我很难想象在这种情况下Deque何时不能满足你的需求(Eliott Frisch提到了使用不足的ArrayDeque(。在containsremove的线性复杂性令人望而却步之前,您需要相当大的数据量和/或相当严格的性能要求。在这种情况下,您可能已经更好地自定义设计自己的数据结构了。

通过JEP 431:Sequenced Collections功能将addFirst方法添加到LinkedHashSet中。这是为即将发布的Java版本21安排的。

public void addFirst(E e)

添加一个元素作为此集合的第一个元素(可选操作(。此操作正常完成后,给定的元素将成为此集合的成员,并且它将是相遇顺序中的第一个元素。

如果该集合已经包含该元素,则会在必要时重新定位该元素,使其按相遇顺序排列在第一位。

指定者:
SequencedCollection<E>`接口中的addFirst

参数:
e-要添加的元素

自:
21

序列集合功能添加了三个新接口:SequencedCollectionSequencedSet(扩展了SequencedCollection(和SequencedMap。现有的类和接口已经被改造以使用新的接口:SortedSet&LinkedHashSet实现SequencedSetListDeque实现SequencedCollectionSortedMapLinkedHashMap实现SequencedMap

SequencedCollection中定义了LinkedHashSet上的addFirst方法。

JDK增强方案没有解释为什么LinkedHashSet以前没有addFirst方法。但在其动机部分,它解释了为什么它和其他与序列相关的方法现在被添加。

Java的集合框架缺少一个集合类型,该类型表示具有定义的相遇顺序的元素序列。它还缺乏一套适用于此类集合的统一操作。这些差距一再成为问题和抱怨的根源。

[…]

这是一种不幸的情况。具有已定义相遇顺序的集合的概念存在于集合框架中的多个位置,但没有单一的类型来表示它。因此,对此类集合的一些操作不一致或缺失,以相反顺序处理元素从不方便到不可能。我们应该填补这些空白。

相关内容

  • 没有找到相关文章

最新更新