hashmap中的key是有序的么_LinkedHashMap为什么是有序的(与put先后顺序一致)

絮叨絮叨

首先呢,明白一点 LinkedHashMap是HashMap的子类,也就是说它就是一个HashMap(所以还是要对HashMap源码有一定了解),至于它可以保证(有序)先后顺序,只能说儿子比老子优秀!虎父无犬子,儿子在父亲的基业上又有了独到之处!原因呢?下面一起看看源码((基于jdk1.8)就知晓了!(看源码一定要有耐心,第一次看可能看不懂,后面再看可能还是看不懂,但是别放弃治疗)。

public class LinkedHashMap

extends HashMap

implements Map{

}

源码分析

变量分析

LinkedHashMap在HashMap基础上扩展的这两个成员变量要特别注意,这两个变量是保证有序的基础

/*** The head (eldest) of the doubly linked list.

* 记录第一个 key—value 对象关于LinkedHashMap.Entry的结构接下来就会分析

*/

transient LinkedHashMap.Entryhead;/*** The tail (youngest) of the doubly linked list.

* 保存最后一个 key—value 对象*/

transient LinkedHashMap.Entry tail;

LinkedHashMap.Entry结构:

它继承了HashMap.Node,  添加了两个LinkedHashMap.Entry 用来记录它的前一个 和后一个put进入来的key-value对象(LinkedHashMap.Entry),在在结构设计上保证了LinkedHashMap有序的可实现

static class Entry extends HashMap.Node{

//它的前一个 和后一个put进入来的key-value对象

Entrybefore, after;

Entry(int hash, K key, V value, Nodenext) {super(hash, key, value, next);

}

}

附上HashMap.Node

static class Node implements Map.Entry{final inthash;finalK key;

V value;

Nodenext;

Node(int hash, K key, V value, Nodenext) {this.hash =hash;this.key =key;this.value =value;this.next =next;

}//省略。。。。。。。

}

实现

了解完结构我们再来看看它在代码中是如何实现的,LinkedHashMap是HashMap的子类 ,在放入key-value时,它复用了HashMap的put方法

publicV put(K key, V value) {return putVal(hash(key), key, value, false, true);

}final V putVal(int hash, K key, V value, booleanonlyIfAbsent,booleanevict) {

Node[] tab; Node p; intn, i;if ((tab = table) == null || (n = tab.length) == 0)

n= (tab =resize()).length;if ((p = tab[i = (n - 1) & hash]) == null)//这里要格外注意 LinkedHashMap复写了HashMap的//newNode(hash, key, value, null) 方法

tab[i] =newNode(hash, key, value, null);//......

}

LinkedHashMap复写了HashMap的newNode(hash, key, value, null) 方法,代码如下:

1 Node newNode(int hash, K key, V value, Nodee) {2 LinkedHashMap.Entry p =

3 new LinkedHashMap.Entry(hash, key, value, e);4 linkNodeLast(p);5 returnp;6 }7 /***有序的实现核心***/

8 private void linkNodeLast(LinkedHashMap.Entryp) {9 LinkedHashMap.Entry last =tail;10 tail =p;11 if (last == null)12 head =p;13 else{14 p.before =last;15 last.after =p;16 }17 }

举一个场景来说明上面的有序核心实现方法,比如说有这么一个场景:  一个班有 1号小明同学 2号张三 3号小红 4号李四同学,老师要知道学生进入教师的先后顺序。老师在黑板上写了 两个词  head,tail两个字段 规定:

1.第一个来的在 head来的在head、tail写上自己的名字

2.第二个及后续到的, 看到黑板上的tail字段后,找到这个同学(这个同学记住我之后到的 after) 通知自己到了(并记住在我之前的是这个同学before) 并修改tail字段为自己的名字

例子:

1.小明同学 第一个到  ,在黑板上 head,tail 都写下 小明

2.张三到了之后看到 tail是小明 记住 自己上一个(before)是小明 ,并修改tail为张三 ,通知小明,小明记下来自己的后面(afte)r是张三

3小红到了看到tail是张三 记住自己上一个(before)是张三 并修改tail为小红,通知张三,张三记下来自己的后面(after)是小红

4李四到了。。。。。。。

老师来了上课 看到head上写的是小明  并询问 小明 你后面是谁 , 小明回:小红 再询问 小红 ....知道 询问到李四 结束

老师就知道了学生进入教室的顺序 小明->张三->小红->李四。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值