Java集合中的LinkedHashSet源码解读
作者:理想万岁万万岁
一、介绍
前面文章中我们从源码详细介绍了继承于HashMap的LinkedHashMap,并通过图片示例讲解了LinkedHashMap是如何在HashMap的哈希表上将各个节点通过双向链表串起来的。
也讲解了基于HashMap实现的HashSet,那么是否存在类似于LinkedHashMap原理的一种Set集合?答案是肯定的,而且是我们本篇文章要讲的LinkedHashSet
顾名思义,LinkedHashSet是基于LinkedHashMap实现的一个Set集合。
另外,本片文章虽然不长,但是对前置知识点有着很强的依赖,需要掌握的前置知识有:HashMap(必选)、红黑树(可选)、LinkedHashMap(必选)、HashSet(必选)
二、类的声明
public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable
从类的声明中可以看到
- 继承HashSet,表示LinkedHashSet是对HashSet的扩展。
- 实现set接口,满足Set集合的定义
- 实现了Cloneable接口,提供了对象克隆方法,但请注意,是浅克隆。
- 实现了Serializable接口,支持序列化。
三、构造方法
前面我们在讲HashSet的构造方法时,其中有一个构造方法我们做了特殊对待,如下所示
HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }
该构造方法创建的map对象的类型是LinkedHashMap,不同于其他构造方法创建的HashMap对象。
而且我们有个关键点不要忽略,在LinkedHashMap中,双向链表的遍历顺序通过构造方法指定,如果没有指定,则使用默认顺序为插入顺序,即accessOrder=false。因此,上面的构造方法所创建的LinkedHashMap对象的双向链表遍历顺序为插入顺序。
且该构造方法就是为了给其子类LinkedHashSet使用的。我们往下看
无参构造
创建LinkedHashMap实例为内部属性,并指定底层哈希表的初始容量为16,加载因子为0.75
public LinkedHashSet() { super(16, .75f, true); }
指定初始容量
创建LinkedHashMap实例为内部属性,并指定底层哈希表的初始容量为initialCapacity,加载因子为0.75
public LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); }
指定初始容量和加载因子
创建LinkedHashMap实例为内部属性,并指定底层哈希表的初始容量为initialCapacity,加载因子为loadFactor
public LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); }
通过集合构造
虽然说LinkedHashSet的底层是LinkedHashMap,但终究还是哈希表+双向链表,需要对哈希表的容量进行计算以避免频繁的扩容。
创建LinkedHashMap实例作为内部对象后,通过addAll()方法将集合中的元素逐一保存,addAll()方法作为一个批量保存模版由其父类AbstractCollection提供,其中的add()方法由父类HashSet实现,这是设计模式—模版方法的体现。
public LinkedHashSet(Collection<? extends E> c) { super(Math.max(2*c.size(), 11), .75f, true); addAll(c); } public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; }
四、最后
看了LinkedHashSet的源码后,发现它只提供了以上几个构造函数,却没有提供各个方法。
这是因为它继承于HashSet,因此HashSet中提供的方法都是可以被LinkedHashSet对象调用的,如add()、remove()、contains()等方法。所以不再过多介绍,
五、结论
- LinkedHashSet内部维护一个LinkedHashMap对象,其底层数据结构为哈希表+链表+红黑树+双向链表
- LinkedHashSet对内部双向链表的遍历顺序为插入顺序
到此这篇关于Java集合中的LinkedHashSet源码解读的文章就介绍到这了,更多相关LinkedHashSet源码解读内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!