为什么LinkedHashSet没有addFirst方法?

问题描述 投票:0回答:2

正如

LinkedHashSet
的文档所述,它是

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

所以它本质上是一个

HashSet
具有由链表实现的 FIFO 键队列。考虑到
LinkedList
Deque
并且特别允许在开头插入,我想知道为什么
LinkedHashSet
除了
addFirst(E e)
接口中存在的方法之外没有
Set
方法。实现起来似乎并不难。

java linked-list deque linkedhashset
2个回答
1
投票

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

… 这个链表定义了迭代排序,也就是顺序 其中元素被插入到集合中(insertion-order)。 …

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

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

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

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

虽然理论上我可以理解您的观点,即可能存在您想要具有 set 属性的双端队列(重复项被忽略/消除)的情况,但我很难想象

Deque
何时无法满足您的需求在这种情况下(Eliott Frisch 提到了未充分使用的
ArrayDeque
)。在
contains
remove
的线性复杂性令人望而却步之前,您需要相当大量的数据和/或非常严格的性能要求。在那种情况下,您可能已经更好地自定义设计自己的数据结构。


0
投票

addFirst
方法被
JEP 431:Sequenced Collections
功能添加到LinkedHashSet。这是为即将到来的 Java 21 版安排的。

public void addFirst(E e)

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

如果这个集合已经包含元素,它会在必要时重新定位,以便它在遇到顺序中排在第一位。

指定者:

addFirst
在界面中
SequencedCollection<E>
`

参数:

e
- 要添加的元素

自:
21

有序集合功能添加了三个新接口:

SequencedCollection
SequencedSet
(扩展
SequencedCollection
)和
SequencedMap
。现有的类和接口已经过改造以使用新接口:
SortedSet
LinkedHashSet
实现
SequencedSet
List
Deque
实现
SequencedCollection
,以及
SortedMap
LinkedHashMap
实现
SequencedMap

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

JDK enhancement proposal并没有解释为什么

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

Java 的 collections 框架 缺少一个集合类型来表示具有定义的遇到顺序的元素序列。它还缺乏适用于此类集合的统一操作集。这些差距一直是问题和投诉的反复来源。

[…]

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

© www.soinside.com 2019 - 2024. All rights reserved.