文档章节

聊聊LinkedHashMap

xpbob
 xpbob
发布于 2018/11/12 13:55
字数 981
阅读 486
收藏 9

LinkedHashMap简介

LinkedHashMap是一个根据某种规则有序的hashmap。根据名字,我们也可以看出这个集合是有hash散列的功能的同时也有顺序。hashmap是无法根据某种顺序来访问数据的,例如放入集合的元素先后的顺序。list都有这个功能,可以根据放入集合的先后来访问具体的数据。这里大家也肯定是有疑问的,例如都已经使用了hash了,为什么还要去保证顺序访问。这个在后面的场景中解释。

LinkedHashMap的实现

当刚遇到这个集合的时候,我也疑惑,能同时满足条件的数据结构究竟是怎么样的。如果没有思考这个问题,还请看到这里好好想想。 ---------滑稽分割-------- 答案确实是没有这样的数据结构。他是两种结构的组合。一种是我们熟悉的hashmap。另外一种就是链表。数据存入集合的时候,先根据hashmap的流程存放入数组中。然后再根据链表的原则,进行链接。 如果看源码,也会发现其实没有多少方法。基本都是继承自hashmap的。

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

我们来看看串联逻辑的几个操作
节点组成

    static class Entry<K,V> extends HashMap.Node<K,V> {
        Entry<K,V> before, after;
        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
    }

可以看出。相比hashmap的节点。linkedhashmap主要增加before, after。可以组成一个双向链表。
节点加入

    private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
        LinkedHashMap.Entry<K,V> last = tail;//获取最后一个节点
        tail = p;//tail指向新加入的节点
        if (last == null)//链表为空
            head = p;
        else {
            p.before = last;
            last.after = p;
        }
    }
    //新建节点的时候把节点加入了双向链表
   Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
        LinkedHashMap.Entry<K,V> p =
            new LinkedHashMap.Entry<K,V>(hash, key, value, e);
        linkNodeLast(p);
        return p;
    }

删除情况也是类似。
节点访问

    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;
    }
    

afterNodeAccess中主要是把访问的节点从原来的位置摘除,加入到尾节点,成为链表的最后一个元素。

使用场景

顺序遍历和快速定位
LinkedHashMap适合有加入顺序和快速定位的场景。我自己开发中遇到过一个场景,就是把配置顺序读取,需要按照读取的顺序访问,而且还需要根据值key直接获取值。这个场景就需要使用LinkedHashMap。
缓存
LinkedHashMap另外一个强大的功能就是做缓存。不过我们要继承一下。去重写一个方法。

   protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {//默认是没有操作
        return false;
    }

这个方法在插入之后会被调用到。

    void afterNodeInsertion(boolean evict) { // possibly remove eldest
        LinkedHashMap.Entry<K,V> first;
        if (evict && (first = head) != null && removeEldestEntry(first)) {//删除第一个元素
            K key = first.key;
            removeNode(hash(key), key, null, false, true);
        }
    }

LinkedHashMap支持两种缓存策略。FIFO和LRU。大家应该也猜到控制策略的地方就是accessOrder。默认为false。就是FIFO。设置为true时就是LRU。因为在访问的时候会调整链表结构,调用afterNodeAccess会把访问的节点放入队列最后。所以每次删除first就可以达到效果。我一般会选择继承LinkedHashMap。然后重写removeEldestEntry,例如可以元素个数达到200范围true。这里需要根据具体场景来编写。

© 著作权归作者所有

xpbob

xpbob

粉丝 98
博文 98
码字总数 80029
作品 0
高级程序员
私信 提问
聊聊springboot2的LoggersEndpoint

序 本文主要研究下springboot2的LoggersEndpoint 实例 GET /actuator/loggers GET /actuator/loggers/com.example POST LoggersEndpointAutoConfiguration spring-boot-actuator-autoconfigu......

go4it
2018/04/25
0
0
聊聊dubbo的LRUCache

序 本文主要研究一下dubbo的LRUCache LRUCache dubbo-2.7.2/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LRUCache.java LRUCache继承了LinkedHashMap,其initialCapacity为1......

go4it
06/20
0
0
性能优化(2.3)-LruCache源码解析

主目录见:Android高级进阶知识(这是总目录索引)  今天我们来聊聊缓存策略相关的内容,LruCache应该说是三级缓存策略会使用到的内存缓存策略。今天我们就来扒一扒这里面的原理,同时也温故...

ZJ_Rocky
2017/11/16
0
0
聊聊spring.cloud.gateway.default-filters

序 本文主要研究下spring.cloud.gateway.default-filters 配置 default-filters,配置的是FilterDefinition对象 FilterDefinition spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/sp......

go4it
2018/06/01
0
0
LinkedHashMap源码笔记

LinkedHashMap介绍 LinkedHashMap继承自HashMap实现Map接口,可以实现有序排列 构造方法 LinkedHashMap的构造方法和HashMap的构造方法都差不多只是每个都加上了 LinkedHashMap 是有序序列acc...

OSC屠夫
2016/09/18
26
0

没有更多内容

加载失败,请刷新页面

加载更多

Linux的基本命令

目录的操作命令(增删改查) 增: mkdir 目录名称; 查: ls 可以看到该目录下的所有的目录和文件 ls -a,可以看到该目录下的所有文件和目录,包括隐藏的 ls -l,可以看到该目录下的所有目录和...

凹凸凸
今天
2
0
在古老unix中增加新用户

Installing 4.3 BSD Quasijarus on SIMH 目标:要在4.3BSD中新增加用户dmr,指定目录/home/dmr,uid为10 gid=31(guest组,系统已建立) 4.3BSD还没有adduser或useradd 直接修改/etc/passwd...

wangxuwei
今天
2
0
Bootstrap(六)表单样式

基本样式 所有设置了 .form-control 类的 <input>、<textarea> 和 <select> 元素都将被默认设置宽度属性为 width: 100%;。 将 label 元素和前面提到的控件包裹在 .form-group 中可以获得最好...

ZeroBit
昨天
3
0
SSL 证书格式转换

SSL 证书格式转换 不同服务器情况下,需要不同的证书格式。 比如 pem 转 pfx。 pem在window 平台下可以导入,但是无法正常使用。 需要转换成pfx。 推荐在线转换工具,由中国数字证书网站提供...

DrChenXX
昨天
2
0
HAProxy

xx

Canaan_
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部