Java容器类框架分析(6)LinkedHashSet源码分析

278 阅读2分钟

在分析LinkedHashSet的时候,先看一下它的继承关系

LinkedHashSet的继承关系
LinkedHashSet的继承关系

可以看到LinkedHash继承自HashSet,即拥有HashSet的全部属性,接着来看一下源码中的注释

  • Hash table and linked list implementation of the Set interface,
    with predictable iteration order. This implementation differs from
    HashSet in that it maintains a doubly-linked list running through
    all of its entries. This linked list defines the iteration ordering,
    which is the order in which elements were inserted into the set
    (insertion-order). Note that insertion order is not affected
    if an element is re-inserted into the set.
  • 这个类是实现了Set接口的哈希表跟链表。此实现类跟HashSet的区别在于它内部持有一个双链表并且存储了所有的entry。这个链表定义了迭代的顺序,该顺序就是元素被插入Set的顺序。注意如果一个元素被重复插入,迭代顺序是不会被影响的。

看到这里,感觉其实跟HashSet一个套路,底层都不是自己实现的,而是通过内部实现的一个LinkedHashMap来维护的,所谓HashSet取地是HashMap的key,HashSet取地是LinkedHashMap的Key,下面从源码的角度来验证一下。

正文

成员变量

就一个序列化Id,其余的全部继承自HashSet

    private static final long serialVersionUID = -2851667679971038690L;

构造方法

     public LinkedHashSet() {
        super(16, .75f, true);
    }
      public LinkedHashSet() {
        super(16, .75f, true);
    }
     public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    public LinkedHashSet() {
        super(16, .75f, true);
    }

可以发现,不管是调用哪一个构造方法,最后调用的都是调用的同一个父类方法,也就是上一篇HashSet中的一个LinkedHashMap的初始化方法,最终还是初始化了一个LinkedHashMap

  HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

Over

当我还想继续查看的时候,发现其实已经没有可以分析的了,没有复写HashSet的其它方法,所以,LinkedHashSet内部没有做过很多的实现,只是调用了HashSet的初始化LinkedHashMap的构造方法,剩余的操作跟HashSet实际上是一样的,没有什么区别。

总结

  1. LinkedHashSet中的LinkedHash跟LinkedHashMap中的LinkedHash实际上是一样的,哈希表跟链表
  2. LinkedHashSet跟HashSet都是非线程安全的,不允许重复元素
  3. LinkedHashSet都允许插入null,插入的元素需要复写hashcode跟equals方法