源码分析——LinkedHashMap

理解了HashMap就可以很容易理解LinkedHashMap了,首先来看一下LinkedHashMap所处的体系结构:

从上面可以看出LinkedHashMap处于Map接口中,作为HashMap的一个子类,其继承了HashMap的方法,并且比它多了一项特性,也就是可以保证输入的顺序和输出的顺序是一样的。接下来继续看其如何实现:

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

由于它继承的是HashMap这个类,因此自然也继承了HashMap的所有接口,所以也就不需要再重复实现了,除此之外,LinkedHashMap还实现了Map接口。

再继续看其成员变量:

private static final long serialVersionUID = 3801124242820219131L;
//序列化标识符,用于反序列化
		
transient LinkedHashMap.Entry<K,V> head;
//头结点,不被序列化
		
transient LinkedHashMap.Entry<K,V> tail;
//尾结点,不被序列化
		
final boolean accessOrder;
//设置顺序,true:按访问顺序排序,false:按插入顺序排序

static class Entry<K,V> extends HashMap.Node<K,V>{
//静态内部类,继承自HashMap中的Node内部类
	Entry<K,V> before, after;
	//多了两个Entry指针,分别指向前一个Entry和后一个Entry
	Entry(int hash, K key, V value, Node<K,V> next){
	//构造器,传的值也是一样的
	super(hash,key,value,next);
}

由于LinkedHashMap是继承了HashMap的,所以也继承了其中所有的非final修饰的成员变量,因此LinkedHashMap在此继承上还增加了head、tail、accessOrder三个成员变量,head和tail主要是作为头结点和尾结点的标志,accessOrder是作为以何种顺序排序的判断,如果为true,则表示按访问顺序,将最近访问的放入链表的尾部,而为false,则表示按照插入的顺序排序。从此可以看出,LinkedHashMap是在HashMap的基础上再在所有的键值对上面建立一个链表,该链表的键值对排列的顺序即accessOrder指定的顺序,这样就达成了有序的特点。提醒一下这个有序并不是代表递增或者递减这样的顺序,其实可以说是一种时间顺序。

同样,LinkedHashMap中放置键值对的结点Entry也是继承了HashMap中的Node结点,而且还增加了before和after两个结点指针。即分别指向顺序链表中的前置结点和后置结点。

接下来继续看其构造函数:

public LinkedHashMap(int initialCapacity, float loadFactor){
//构造器1,参数为初始容量与加载因子
	super(initialCapacity,loadFactor);
	//调用父类的构造器
	accessOrder = false;
	//将accessOrder设置为false,即按插入顺序排序
}
		
public LinkedHashMap(int initialCapacity){
//构造器2,参数为初始容量
	super(initialCapacity);
	//调用父类构造器
	accessOrder = false;
	//设置accessOrder为false,按插入顺序排序
}
		
public LinkedHashMap(){
//构造器3,空参
	super();
	accessOrder = false;
}
		
public LinkedHashMap(Map<? extends K, ? extends V> m){
//构造器4,参数为Map类容器
	super();
	accessOrder = false;
	putMapEntries(m,false);
}
		
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder){
//构造器5,参数为初始容量、加载因子以及访问顺序
//此构造器可以自己设置链表排列顺序为插入顺序还是访问顺序
	super(initialCapacity, loadFactor);
	this.accessOrder = accessOrder
}

LinkedHashMap包含五个构造器,当传入的是初始容量与加载因子,则先调用父类构造器,并将accessOrder置为false,即顺序为插入顺序;如果传入的是初始容量,则将加载因子置为默认值,将accessOrder也置为false,再调用父类构造器;当传入的为空参,则将直接调用父类空参构造器并将accessOrder置为false;当传入的是一个Map集合类,则先调用父类空参构造器,再将accessOrder置为false,并调用putMapEntries将键值对依次放入LinkedHashMap中;当传入的是一个初始容量、加载因子与accessOrder时,则按照传入的参数先调用父类构造器,再设置accessOrder。总之,如果不设置accessOrder参数,则其为默认false,即默认是按照插入顺序排序,当然可以通过构造器设置accessOrder为访问顺序排序。

接下来再研究一下其常用方法:

1.get

public V get(Object key){
//此处重写的目的是判断本容器是按插入顺序排序还是按访问顺序
//如果是第二种,则当找到了该键值对,该键值对就得移动到链表的尾部
	Node<K,V> e;
	if((e = getNode(hash(key), key)) == null)
		return null;
	if(accessOrder)
		afterNodeAccess(e);
	return e.value;
}

由于LinkedHashMap是直接继承HashMap类的,所以HashMap中的常用的get、put、remove、clear等方法是可以直接用的,而对于get方法两者的最大的区别就是当LinkedHashMap的accessOrder设置为true时,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值