源码分析——LinkedHashSet

本文介绍了LinkedHashSet,它是HashSet的有序版本。文章分析了LinkedHashSet的构造器、成员变量、继承体系以及常用方法,包括add、remove、contains、size、clear和isEmpty。LinkedHashSet通过内部的链表保持元素的插入或访问顺序,区别于HashSet。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LinkedHashSet对于HashSet就如LinkedHashMap对于HashMap一样,因此也很容易理解。

首先,继续看一看它所处的体系结构:

由于HashSet是无序的,因此LinkedHashSet主要的特点是让自己的元素保持一定的顺序。

继续看它的继承体系:

LinkedHashSet继承自HashSet,并实现了HashSet一样的接口,至于这些接口的方法也就不赘述了。

class LinkedHashSet<E> extends HashSet<E>
			implements Set<E>, Cloneable, java.io.Serializable{

再继续看看它的成员变量:

private static final long serialVersionUID = -2851667679971038690L;
//序列化标志,用于反序列化

发现它自己根本就没有任何成员变量,都是通过HashSet继承而来的。

继续看其构造器:

public LinkedHashSet(int initialCapacity, float loadFactor){
	//构造器1,参数为默认容量与加载因子,调用父类构造器
	super(initialCapacity, loadFactor, true);
	//此处的true是为了找到准确的父类构造器,即能够创建LinkedHashMap类的构造器
}

public LinkedHashSet(int initialCapacity){
	//构造器2,参数为默认容量,默认加载因子为0.75
	super(initialCapacity,.75f,true);
}

public LinkedHashSet(){
	//构造器3,空参,默认容量为16,默认加载因子为0.75
	super(16,.75f,true);
}

public LinkedHashSet(Collection<? extends E> c){
	//构造器4,传入一个集合c
	super(Math.max(2 * c.size(),11),.75f,true);
	//这里的capacity为什么要这样设置????
	addAll(c);
}
HashSet(initialCapacity, float loadFactor, boolean dummy){
	//构造器5,非公开的,用于创造一个有序的HashMap,此处是为LinkedHashSet留后路
	map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

 

LinkedHashSet有四个构造器,当参数为初始容量与加载因子时,直接调用父类的构造器,由于上一篇讲过了,其父类HashSet构造器有五个,而其最后一个构造器的参数是初始容量、加载因子与一个无用的dummy。而这个dummy则是用于LinkedHashSet的构造器调用的识别器。进入父类构造器后再创建LinkedHashMap类并将其赋给map。当参数为初始容量时,则将加载因子设置为0.75再调用父类的构造器;当为空参时,则设置初始容量为16,默认加载因子为0.75再调用父类构造器;当参数为集合c时,首先根据c的大小获得合适的初始容量(此处有些不解,为什么要取c大小的两倍和11的最大值作为初始容量,这种取值方法只在Hashtable中见过,笔误?但是这个传进去最后在HashMap中还是要转化成16或者2的整数次幂,也不影响其构造,但是查阅网络资料也没有获得一个比较好的解释,疑问暂留)再将加载因子设置为0.75并调用父类构造器。

除了构造器之外,LinkedHashSet没有其他的常用方法了,都是从HashSet中继承来到方法,并且可以直接使用,HashSet和LinkedHashSet两者唯一的区别就是LinkedHashSet比HashSet多了一个可以分别结点插入顺序或访问顺序的链表。

常用方法:

1.add

2.remove

3.contains

4.size

5.clear

6.isEmpty

 

总源码

public class LinkedHashSet<E> extends HashSet<E>
							implements Set<E>, Cloneable, java.io.Serializable{
		//LinkedHashSet继承于HashSet,建立于LinkeHashMap之上,其余的都和HashSet差不多
		
		private static final long serialVersionUID = -2851667679971038690L;
		//序列化标志,用于反序列化
		
		public LinkedHashSet(int initialCapacity, float loadFactor){
			//构造器1,参数为默认容量与加载因子,调用父类构造器
			super(initialCapacity, loadFactor, true);
			//此处的true是为了找到准确的父类构造器,即能够创建LinkedHashMap类的构造器
		}

		public LinkedHashSet(int initialCapacity){
			//构造器2,参数为默认容量,默认加载因子为0.75
			super(initialCapacity,.75f,true);
		}

		public LinkedHashSet(){
			//构造器3,空参,默认容量为16,默认加载因子为0.75
			super(16,.75f,true);
		}

		public LinkedHashSet(Collection<? extends E> c){
			//构造器4,传入一个集合c
			super(Math.max(2 * c.size(),11),.75f,true);
			//这里的capacity为什么要这样设置????
			addAll(c);
		}
		
		@Override
		public Spliterator<E> spliterator(){
			//获取分割器
			return Spliterators.spliterator(this,Spliterator.DISTINCT | Spliterator.ORDERED);
		}
	}

参考资料:

https://www.cnblogs.com/tong-yuan/p/LinkedHashSet.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值