Module java.base
Package java.util

Class LinkedHashSet<E>

类型参数:
E - 此集合中维护的元素类型
所有实现的接口:
Serializable, Cloneable, Iterable<E>, Collection<E>, SequencedCollection<E>, SequencedSet<E>, Set<E>

public class LinkedHashSet<E> extends HashSet<E> implements SequencedSet<E>, Cloneable, Serializable

LinkedHashSetSet接口的哈希表和链表实现,具有明确定义的遍历顺序。此实现与HashSet不同之处在于它维护一个双向链表,通过其所有条目。此链表定义了遍历顺序,即元素插入到集合中的顺序(插入顺序)。最近插入的元素(最老的)在前,最年轻的元素在后。请注意,如果使用add方法将元素重新插入到集合中,则遍历顺序不受影响(如果在调用s.add(e)之前s.contains(e)会立即返回true,则元素e将被重新插入到集合s中)。此集合的逆序视图是相反的顺序,最年轻的元素首先出现,最老的元素最后出现。已在集合中的元素的遍历顺序可以通过使用addFirstaddLast方法来更改。

此实现使其客户端免受HashSet提供的未指定、通常混乱的排序的影响,而又不会增加与TreeSet相关的成本。它可用于生成具有与原始集合相同顺序的集合副本,而不考虑原始集合的实现方式:


     void foo(Set<String> s) {
         Set<String> copy = new LinkedHashSet<>(s);
         ...
     }
 
如果模块接收一个集合作为输入,复制它,然后返回结果,其顺序由副本的顺序确定,这种技术特别有用。 (客户通常希望以与呈现顺序相同的顺序返回事物。)

此类提供所有可选的SetSequencedSet操作,并允许空元素。与HashSet一样,它为基本操作(addcontainsremove)提供恒定时间性能,假设哈希函数将元素正确分散在桶中。由于维护链表的额外开销,性能可能略低于HashSet,但有一个例外:遍历LinkedHashSet需要与集合的大小成正比的时间,而不考虑其容量。遍历HashSet可能更昂贵,需要与其容量成正比的时间。

链接哈希集有两个影响其性能的参数:初始容量负载因子。它们的定义与HashSet完全相同。但请注意,对于此类选择过高的初始容量值的惩罚比对于HashSet要小,因为此类的迭代时间不受容量的影响。

请注意,此实现不是同步的。如果多个线程同时访问链接哈希集,并且至少有一个线程修改了集合,则必须在外部进行同步。通常通过在自然封装集合的某个对象上同步来实现这一点。如果不存在这样的对象,则应使用Collections.synchronizedSet方法对集合进行“包装”。最好在创建时执行此操作,以防止意外的非同步访问集合:

   Set s = Collections.synchronizedSet(new LinkedHashSet(...));

此类的iterator方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间修改了集合,除非通过迭代器自己的remove方法,否则迭代器将抛出ConcurrentModificationException。因此,在面对并发修改时,迭代器会快速且干净地失败,而不是在未来的某个不确定时间冒险进行任意的、非确定性的行为。

请注意,迭代器的快速失败行为不能保证,因为一般来说,在存在非同步并发修改的情况下,不可能做出任何硬性保证。快速失败迭代器基于尽力而为的基础抛出ConcurrentModificationException。因此,编写依赖此异常正确性的程序是错误的:迭代器的快速失败行为应仅用于检测错误。

此类是Java集合框架的成员。

自 JDK 版本:
1.4
参见:
  • Constructor Details

    • LinkedHashSet

      public LinkedHashSet(int initialCapacity, float loadFactor)
      构造一个具有指定初始容量和负载因子的新的空链接哈希集。
      API 注意:
      要创建一个初始容量适应预期元素数量的LinkedHashSet,请使用newLinkedHashSet
      参数:
      initialCapacity - 链接哈希集的初始容量
      loadFactor - 链接哈希集的负载因子
      抛出:
      IllegalArgumentException - 如果初始容量小于零,或者负载因子为非正数
    • LinkedHashSet

      public LinkedHashSet(int initialCapacity)
      构造一个具有指定初始容量和默认负载因子(0.75)的新的空链接哈希集。
      API 注意:
      要创建一个初始容量适应预期元素数量的LinkedHashSet,请使用newLinkedHashSet
      参数:
      initialCapacity - LinkedHashSet的初始容量
      抛出:
      IllegalArgumentException - 如果初始容量小于零
    • LinkedHashSet

      public LinkedHashSet()
      构造一个具有默认初始容量(16)和负载因子(0.75)的新的空链接哈希集。
    • LinkedHashSet

      public LinkedHashSet(Collection<? extends E> c)
      构造一个具有与指定集合相同元素的新链接哈希集。链接哈希集是使用足以容纳指定集合中元素的初始容量和默认负载因子(0.75)创建的。
      参数:
      c - 要放入此集合中的元素的集合
      抛出:
      NullPointerException - 如果指定的集合为null
  • Method Details

    • spliterator

      public Spliterator<E> spliterator()
      创建一个在此集合中的元素上创建延迟绑定快速失败Spliterator

      Spliterator报告Spliterator.SIZEDSpliterator.DISTINCTORDERED。实现应该记录其他特征值的报告。

      指定由:
      spliterator 在接口 Collection<E>
      指定由:
      spliterator 在接口 Iterable<E>
      指定由:
      spliterator 在接口 Set<E>
      覆盖:
      spliterator 在类 HashSet<E>
      实现说明:
      该实现从集合的Iterator创建一个延迟绑定的分割迭代器。分割迭代器继承集合的迭代器的快速失败属性。创建的Spliterator还会报告Spliterator.SUBSIZED
      返回:
      该集合中元素的Spliterator
      自Java版本:
      1.8
    • newLinkedHashSet

      public static <T> LinkedHashSet<T> newLinkedHashSet(int numElements)
      创建一个新的、空的LinkedHashSet,适合预期元素数量。返回的集合使用默认的负载因子0.75,并且其初始容量通常足够大,以便可以添加预期数量的元素而无需调整集合大小。
      类型参数:
      T - 新集合中维护的元素类型
      参数:
      numElements - 预期元素数量
      返回:
      新创建的集合
      抛出:
      IllegalArgumentException - 如果numElements为负数
      自Java版本:
      19
    • addFirst

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

      如果此集合已包含该元素,则必要时将其重新定位,以使其成为遇到顺序中的第一个元素。

      指定由:
      addFirst 在接口 SequencedCollection<E>
      参数:
      e - 要添加的元素
      自Java版本:
      21
    • addLast

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

      如果此集合已包含该元素,则必要时将其重新定位,以使其成为遇到顺序中的最后一个元素。

      指定由:
      addLast 在接口 SequencedCollection<E>
      参数:
      e - 要添加的元素
      自Java版本:
      21
    • getFirst

      public E getFirst()
      获取此集合的第一个元素。
      指定由:
      getFirst 在接口 SequencedCollection<E>
      返回:
      检索到的元素
      抛出:
      NoSuchElementException - 如果此集合为空
      自Java版本:
      21
    • getLast

      public E getLast()
      获取此集合的最后一个元素。
      指定由:
      getLast 在接口 SequencedCollection<E>
      返回:
      检索到的元素
      抛出:
      NoSuchElementException - 如果此集合为空
      自Java版本:
      21
    • removeFirst

      public E removeFirst()
      移除并返回此集合的第一个元素(可选操作)。
      指定由:
      removeFirst 在接口 SequencedCollection<E>
      返回:
      被移除的元素
      抛出:
      NoSuchElementException - 如果此集合为空
      自Java版本:
      21
    • removeLast

      public E removeLast()
      移除并返回此集合的最后一个元素(可选操作)。
      指定由:
      removeLast 在接口 SequencedCollection<E>
      返回:
      被移除的元素
      抛出:
      NoSuchElementException - 如果此集合为空
      自Java版本:
      21
    • reversed

      public SequencedSet<E> reversed()
      返回此集合的逆序视图。返回视图中元素的遇到顺序与此集合中元素的遇到顺序相反。逆序排序会影响所有对顺序敏感的操作,包括对返回视图的集合的操作。如果集合实现允许修改此视图,则对底层集合的修改会“写入”到该视图。对逆序视图的修改是允许的,并将传播到此集合。此外,对此集合的修改将在逆序视图中可见。
      指定由:
      reversed 在接口 SequencedCollection<E>
      指定由:
      reversed 在接口 SequencedSet<E>
      返回:
      作为SequencedSet的此集合的逆序视图
      自Java版本:
      21