概述

对于LinkedHashSet而言,它继承与HashSet、又基于LinkedHashMap来实现的。LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承与HashSet,其所有的方法操作上又与HashSet相同,因此LinkedHashSet 的实现上非常简单,只提供了四个构造方法,并通过传递一个标识参数,调用父类的构造器,底层构造一个LinkedHashMap来实现,在相关操作上与父类HashSet的操作相同,直接调用父类HashSet的方法即可。
image.png

源码分析

  1. package java.util;
  2. // LinkedHashSet继承自HashSet
  3. public class LinkedHashSet<E>
  4. extends HashSet<E>
  5. implements Set<E>, Cloneable, java.io.Serializable {
  6. private static final long serialVersionUID = -2851667679971038690L;
  7. // 传入容量和装载因子
  8. public LinkedHashSet(int initialCapacity, float loadFactor) {
  9. super(initialCapacity, loadFactor, true);
  10. }
  11. // 只传入容量, 装载因子默认为0.75
  12. public LinkedHashSet(int initialCapacity) {
  13. super(initialCapacity, .75f, true);
  14. }
  15. // 使用默认容量16, 默认装载因子0.75
  16. public LinkedHashSet() {
  17. super(16, .75f, true);
  18. }
  19. // 将集合c中的所有元素添加到LinkedHashSet中
  20. // 好奇怪, 这里计算容量的方式又变了
  21. // HashSet中使用的是Math.max((int) (c.size()/.75f) + 1, 16)
  22. public LinkedHashSet(Collection<? extends E> c) {
  23. super(Math.max(2*c.size(), 11), .75f, true);
  24. addAll(c);
  25. }
  26. // 可分割的迭代器, 主要用于多线程并行迭代处理时使用
  27. @Override
  28. public Spliterator<E> spliterator() {
  29. return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
  30. }
  31. }

总结

  1. LinkedHashSet 是 Set 的一个具体实现,其维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可为插入顺序或是访问顺序。
  2. LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的(具体的区别大家可以自己去思考一下)。
  3. 如果我们需要迭代的顺序为插入顺序或者访问顺序,那么 LinkedHashSet 是需要你首先考虑的。