LinkedHashMap是如何实现有序的

1.LinkedHashMap有序



    若是你用过HashMap那么确定知道HashMap是不能保证有序性的,之因此HashMap不能保证有序性是由于存放数组位置的数据时根据hash函数决定的;可是有没有可以保证有序性的Map呢?那就是LinkedHashMap,下面咱们经过代码来看一下HashMap的无序和LinkedHashMap的有序性。数组



    HashMap无序微信






    LinkedHashMap有序app






    LinkedHashMap一共有5个构造方法,其中有4个的构造方法都是指定了accessOrder为false,只有第一个能够自定义accessOrder的状态,accessOrder实际上就是指定排序的规则;若是accessOrder为false表示根据插入的顺序进行排序,当为true的时候表示根据获取排序。可看以下实例代码less






    插入顺序为45,55,53而后获取了55,45排序顺序变为53,44,45。编辑器







2.LinkedHashMap源码



    一样在看源码以前咱们先看一下LinkedHashMap的继承与实现关系图。能够看到LinkedHashMap继承HashMap,同时实现了Map接口。函数





    LinkedHashMap对HashMap的newNode、afterNodeAccess、afterNodeInsertion方法进行都进行了重写,同时也对HashMap中的Node进行了重写增长了before和after字段spa









    回到LinkedHashMap的put方法。当咱们debug进入到LinkedHashMap后实际上就是调用了HashMap的put方法。.net





    在putVal中先判断Node是否须要为空,为空进行初始化,若是不为判断对应数组下标中是否有值,若是没有调用newNode方法。在newNode中调用linkNodeLast。debug





    linkNodeLast拿到尾部节点。若是尾部为空直接把第一个当前节点设置为头和尾节点,若是不为空则拿到尾部节点同时将当前节点的before设置为尾部节点即前一个节点,而将前一个节点的after设置为当前节点。这个before和after是否是就是一个双向链表的意思。3d





    在HashMap中实际上并无对afterNodeInsertion方法进行任何实现,而在LinkedHashMap中作了具体的实现操做。可是在JDK8中不会执行,由于removeEldestEntry方法始终返回false。





    实际上LinkedList可以实现有序就是由于重写了Node并增长了before和after字段,同时对newNode方法进行了重写,有序就是由于before和after字段



3.get方法



    LinkedHashMap的get方法与HashMap中get方法的不一样点也在于多了afterNodeAccess()方法。afterNodeAccess方法在执行时必须accessOrder为true,也就是必须是根据获取排序时才会执行。





    详细看一下afterNodeAccess是怎么实现的,afterNodeAccess实际上就是把当前获取的节点的after和before进行从新变化,也就是移动到最后面去。





3.remove方法



    reomve方法也直接使用了HashMap中的remove,LinkedHashMap重写了其中的afterNodeRemoval该方法在HashMap中没有具体实现,经过此方法在删除节点的时候调整了双链表的结构。





4.总结



    LinkedHashMap之因此能保证有序性是由于在HashMap的Node基础上又增长了after和before字段,至关有又是一个双向链表来维护有序性。结构以下





本文分享自微信公众号 - 大猫的Java笔记(damaoJava)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索